【项目介绍】协程——C语言实现的用户态非抢占式轻量级线程
生活随笔
收集整理的這篇文章主要介紹了
【项目介绍】协程——C语言实现的用户态非抢占式轻量级线程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 項目介紹
- 開發語言
- 開發環境
- 項目簡介
- 項目特點
- 適用場景
- 發布鏈接
- 使用介紹
- 上下文環境
- 宏
- 協程狀態
- 協程與調度器結構體
- 接口
- 示范用例
- 使用協程實現一個TCP服務器
項目介紹
開發語言
C
開發環境
CentOS7、vim、gcc、gdb、git、MakeFile
項目簡介
“協程”即用戶態下的非搶占式的輕量級線程,是一種在程序開發中處理多任務的組件。
由于在C/C++中并沒有引入協程這一概念,而大部分開源的庫又過于重量,所以我基于ucontext組件實現了一個簡單的協程庫
項目特點
- 用戶態實現協程的調度切換,減少了內核切換的開銷。
- 非搶占式,用戶自己實現調度,同一時間只能有一個協程在執行,由協程主動交出控制權。
- 基于非對稱(asymmetric)模式, 控制流更加簡單,程序更加結構化。
- 協程具有獨立的棧,確保運行效率。
適用場景
協程主要適用于I/O密集型的場景,如示例中的TCP服務器。在傳統的多路復用+多線程/多進程的做法,每并發一個進程/線程就會消耗內存,并且最嚴重的問題就是由系統來進行調度切換帶來的嚴重損耗,而協程剛好能夠解決這些問題。
發布鏈接
具體的實現請參考源代碼
協程
使用介紹
上下文環境
對于上下文環境的切換可以使用很多方法
- 匯編
- C語言庫函數setjmp, longjmp
- glibc的ucontext組
我在這里使用的是ucontext組件,如果不了解這個組件的使用方法,可以參考我的另一篇博客
ucontext族函數的使用及原理分析
由于ucontext只支持posix,如果需要移植到windows,只需要將api換成fiber的即可
宏
#define STACK_SIZE (1024 * 1024) //協程函數棧大小 #define COROUTINE_SIZE (1024) //協程最大數量協程狀態
協程共設置了四種狀態,READY, RUNNING, DEAD, SUSPEND。下圖描述了所有狀態即狀態之間的轉換關系。
協程與調度器結構體
typedef struct coroutine {void* (*call_back)(struct schedule* s, void* args); //回調函數void* args; //回調函數的參數ucontext_t ctx; //協程的上下文char stack[STACK_SIZE]; //協程的函數棧enum State state; //協程狀態}coroutine;typedef struct schedule {coroutine** coroutines; //協程數組int cur_id; //正在運行的協程下標int max_id; //數組中最大的下標ucontext_t main; //主流程上下文 }schedule;接口
//創建協程序調度器 schedule* schedule_create();//創建協程, 并返回協程所處下標 int coroutine_create(schedule* s, void* (*call_back)(schedule*, void* ), void* args);//協程讓出CPU,返回主流程上下文 void coroutine_yield(schedule* s);//恢復協程上下文 void coroutine_resume(schedule* s, int id);//運行協程 void coroutine_running(schedule* s, int id);//銷毀協程調度器 void schedule_destroy(schedule* s);//判斷協程調度器中的協程是否全部結束, 結束返回1, 沒結束返回0 int schedule_finished(schedule* s);示范用例
使用協程實現一個TCP服務器
思路圖
可以看到該服務器可以快速的響應多個連接
總結
以上是生活随笔為你收集整理的【项目介绍】协程——C语言实现的用户态非抢占式轻量级线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ucontext族函数的使用及原理分析
- 下一篇: 高级数据结构与算法 | B树、B+树、B