基于windows fiber的协程(coroutine)实现
2021-06-29 19:07
标签:expr push cout rda _MSC_VER air ack called 函数 一个非常简单,但是实用的协程实现,使用Windows的 基于windows fiber的协程(coroutine)实现 标签:expr push cout rda _MSC_VER air ack called 函数 原文地址:https://www.cnblogs.com/racaljk/p/10010106.html*Fiber
函数族(linux可以稍微改一下用*context
函数族)。fco.h
#ifndef _MSC_VER
#error "this fast coroutine library only supports MSVC building chain"
#endif
#include
fco.cpp
#include "fco.h"
// Initialize fco library, return a global scheduler
fco::Scheduler* fco::initialize() {
Scheduler* sched = new Scheduler;
sched->currentIdx = ERR_NOT_EXIST_CO;
sched->main = ConvertThreadToFiber(NULL);
return sched;
}
// Release all resources
void fco::destroy(Scheduler* s) {
for (auto& c : s->coroutines) {
DeleteFiber(c.second->winFiber);
}
delete s;
}
// This is should NEVER BE called on user land
void __stdcall fco::__entry(LPVOID lpParameter) {
// Execute the task of current coroutine
Scheduler* s = (Scheduler*)lpParameter;
Coroutine* currentCo = s->coroutines[s->currentIdx];
(currentCo->task)(s, currentCo->userData);
// Clean up executed task
s->coroutines.erase(s->coroutines.find(s->currentIdx));
s->currentIdx = ERR_NOT_EXIST_CO;
currentCo->status = Status::READY;
DeleteFiber(currentCo->winFiber);
delete currentCo;
// Switch to entry function
SwitchToFiber(s->main);
}
// Create new coroutine and return an unique identity
int fco::newco(Scheduler* scheduler, void (*task)(fco::Scheduler*, void*),
void* userData) {
Coroutine* co = new Coroutine;
co->task = task;
co->userData = userData;
co->winFiber = CreateFiber(0, __entry, scheduler);
if (co->winFiber == NULL) {
return ERR_NOT_EXIST_CO;
}
co->status = Status::READY;
int newCoId =
scheduler->coroutines.size() != 0
? scheduler->coroutines.end().operator--().operator*().first + 1
: 0;
scheduler->coroutines.insert(std::make_pair(newCoId, co));
return newCoId;
}
// Resume suspended coroutine by given coid
void fco::resume(fco::Scheduler* scheduler, int coid) {
if (coid coroutines[coid];
if (co->status == Status::READY || co->status == Status::AWAIT) {
scheduler->currentIdx = coid;
scheduler->coroutines[scheduler->currentIdx]->status = Status::AWAIT;
co->status = Status::READY;
SwitchToFiber(co->winFiber);
}
}
// Yield CPU time to main coroutine
void fco::yield(fco::Scheduler* scheduler) {
Coroutine* co = scheduler->coroutines[scheduler->currentIdx];
co->status = Status::AWAIT;
scheduler->currentIdx = ERR_NOT_EXIST_CO;
SwitchToFiber(scheduler->main);
}
// Get current running coroutine identity
int fco::current(Scheduler* scheduler) { return scheduler->currentIdx; }
example
#include
#include
上一篇:Qt窗体圆角
下一篇:RestfulAPI超简单入门
文章标题:基于windows fiber的协程(coroutine)实现
文章链接:http://soscw.com/essay/99509.html