编程语言
首页 > 编程语言> > C++ Win32纤程的简单使用示例

C++ Win32纤程的简单使用示例

作者:互联网

开头的代码是用来本地化错误代码的,跟主体没有关系

主要逻辑在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();


}

 

标签:std,纤程,示例,buffer,cout,C++,errorCode,DWORD,string
来源: https://www.cnblogs.com/leikaifeng/p/14665337.html