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