开头的代码是用来本地化错误代码的,跟主体没有关系
主要逻辑在main方法中
我把本机接口简单包装了一下,所以是通过Fiber类来进行调用
#include <iostream> #include <windows.h> std::string GetWin32ErrorMessage(DWORD errorCode) { char buffer[4096]; auto length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, errorCode, 0, buffer, sizeof(buffer), nullptr); return std::string{ buffer, length }; } void Exit(const std::string& message, DWORD errorCode) { std::cout << message << " " << GetWin32ErrorMessage(errorCode) << std::endl; exit(errorCode); } void Exit(const std::string& message) { Exit(message, GetLastError()); } void Print() { std::cout << std::endl; } template<typename T, typename ...TS> void Print(T value, TS ...values) { std::cout << value << " "; Print(values...); } // // 纤程也是一个执行上下文,比如各个寄存器的值 // 只不过纤程是由用户层面决定调度的 // 线程可以被转换为纤程,也就是创建纤程上下文,这样才能进行纤程之间的切换,也就是把当前上下文保存起来去执行另一个上下文 // 纤程只能由纤程去调度,也就是拥有纤程上下文的执行实体把当前纤程上下文保存,然后装上另一个纤程上下文执行 // 假如拥有执行实体的纤程自己删自己会导致执行实体退出 // 纤程上下文的起始方法退出,那么执行实体就会退出,但是该纤程上下文还有没有效不太清楚,按道理讲指令指针寄存器可能已经指向了非用户代码了,就跟main方法返回了差不多 // 拥有执行实体的纤程上下文自己调度自己的行为未定义 // class Fiber { public: static LPVOID ConvertToFiber() { auto handle = ::ConvertThreadToFiberEx(nullptr, FIBER_FLAG_FLOAT_SWITCH); if (handle == nullptr) { Exit("Convert To Fiber Error"); } return handle; } static void ConvertToThread() { if (::ConvertFiberToThread() == 0) { Exit("Convert To Thread Error"); } } static auto GetCurrentFiber() { return ::GetCurrentFiber(); } static LPVOID Create(LPFIBER_START_ROUTINE func) { auto handle = ::CreateFiberEx(0, 0, FIBER_FLAG_FLOAT_SWITCH, func, Fiber::GetCurrentFiber()); if (handle == nullptr) { Exit("Create Fiber Error"); } return handle; } static void Switch(LPVOID fiber) { if (fiber == Fiber::GetCurrentFiber()) { Exit("Switch Fiber error"); } ::SwitchToFiber(fiber); } static void Delete(LPVOID fiber) { ::DeleteFiber(fiber); } }; int main() { auto one_fiber = Fiber::ConvertToFiber(); auto tow_fiber = Fiber::Create([](auto create_fiber) { Print("子纤程运行"); //Fiber::Delete(Fiber::GetCurrentFiber()); while (true) { Fiber::Switch(create_fiber); Print("子纤程运行"); } }); Print("已经创建了子纤程,但未运行"); Fiber::Switch(tow_fiber); Print("子纤程,调度回来啦"); Fiber::Switch(tow_fiber); Print("子纤程,调度回来啦"); Fiber::Switch(tow_fiber); Print("子纤程,调度回来啦"); Fiber::Delete(tow_fiber); Fiber::ConvertToThread(); }