首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

從零構建跨平台 C 協程庫:Windows Fiber 與 Linux ucontext 統一封裝實戰

     編輯:關於C語言

協程核心概念與優勢

協程是用戶態輕量級線程,由程序員控制調度(同步串行),而非操作系統搶佔式調度。核心優勢:

  • 性能優越:避免內核態切換開銷,單線程內可運行數萬協程
  • 內存高效:棧大小可配置(默認 1MB),遠小於系統線程默認 8MB
  • 邏輯清晰:將異步回調地獄轉化為同步順序代碼,降低認知負荷

跨平台底層機制對比

特性Windows FiberLinux ucontext
核心 APIConvertThreadToFiberEx / CreateFiberEx / SwitchToFibergetcontext / makecontext / swapcontext
棧管理系統自動分配用戶手動分配 uc_stack
上下文傳遞LPVOID 參數 + GetFiberData()makecontext 可變參數
64 位參數傳遞原生支援需拆分高低 32 位組合

統一接口設計

typedef enum { CS_Dead, CS_Ready, CS_Running, CS_Suspend } costatus_e;
typedef struct comng * comng_t;
typedef void (*co_f)(comng_t, void *);

comng_t co_start(void);           // 初始化調度器
void co_close(comng_t);           // 銷毀調度器
int co_create(comng_t, co_f, void *); // 創建協程,返回 ID
void co_resume(comng_t, int);     // 恢復/啟動協程
void co_yield(comng_t);           // 主動讓出 CPU
costatus_e co_status(comng_t, int); // 查詢狀態
int co_running(comng_t);          // 獲取當前運行協程 ID

Windows 實現關鍵點

  • 主協程調用 ConvertThreadToFiberEx 轉為 Fiber
  • CreateFiberEx 創建子協程,指定入口函數 _comain
  • SwitchToFiber 實現雙向切換,GetCurrentFiber 保存當前上下文
  • 協程結束時調用 DeleteFiber 釋放資源,ConvertFiberToThread 恢復線程模式

Linux 實現關鍵點

  • 調度器持有共享棧 comng::stack,協程各自備份棧內容 coroutine::stack
  • makecontext 64 位參數傳遞技巧:將指針拆分高低 32 位分兩個參數傳入,入口函數重組
  • swapcontext 切換前後需手動保存/恢復棧內容(_save_stack / memcpy)
  • 協程結束釋放私有棧內存

融合編譯與測試驗證

通過 #if defined(__GNUC__) / #elif defined(_MSC_VER) 實現單文件跨平台編譯。測試用例創建兩個協程交替打印計數器,雙平台輸出一致:

coroutine 0 : 0
coroutine 1 : 100
coroutine 0 : 1
coroutine 1 : 101
...
main end

項目結構與擴展建議

  • 核心文件:coroutine.h(接口)、coroutine.c(融合實現)
  • 可擴展:IO 多路復用整合(epoll/IOCP)、定時器、通道通信、協程池
  • 參考優秀開源實現:cloudwu/coroutine (GitHub)、libco (騰訊)

本庫採用純 C 實現,無 C++ 依賴,極易集成到嵌入式、遊戲服務器、高性能網關等項目中。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved