ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-04-16 07:01:10  阅读:246  来源: 互联网

标签:std 纤程 示例 buffer cout C++ errorCode DWORD string


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

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有