協程也叫微執行緒,英文名稱為coroutine
。乙個程序可以有多個執行緒,乙個執行緒可以有多個協程,這是協程和執行緒間的關係。不同的是,執行緒由系統排程,但協程需要自己排程,協程執行在使用者態。
linux核心為協程程式設計提供了支援,相關的函式宣告在
ucontext.h
標頭檔案中。也可以借助
longjmp
、setjmp、pthread_attr_setstackaddr
等組合實現,但複雜很多,
ucontext
提供的函式已幫助做了很多任務作。要實現協程的併發(執行緒內的,顯然是假併發,實際還是序列的),要求主動呼叫
swapcontext
進行切換。
協程程式設計實際就是使用者態排程函式的執行次數,讓單個執行緒,看起來像是多執行緒。基於它可以實現偽同步,也就是將非同步變成同步呼叫。
協程的原理非常簡單,假設任務a
劃分成a1、a2
、a3三個子任務,任務
b劃分成任務b1和
b2兩個子任務。利用協程,讓a和
b可以並行進行,比如完成
a1後,立即執行b1,
b1完成後執行a2,
a2完成後執行b2,
b2完成後執行a3。
為達到這個目的,在執行a1時,
a1結束前需要呼叫swapcontext切換到b1
。同理b1
完成時,也需要呼叫swapcontext切換到a2
。下面這個示例可以直接編譯執行,通過它可以體會到協程的效果。
// 協程示例
// 編譯
: g++ -g -o x x.cpp
#include
#include // 協程相關
api所在標頭檔案
#include
// 定義
3個協程,類似於
3個執行緒
static void foo();
static void woo();
static void zoo();
static ucontext_t ctx1; // 協程
zoo的上下文,由
makecontext
呼叫構造
static ucontext_t ctx2; // 協程
woo的上下文,由
makecontext
呼叫構造
static ucontext_t ctx3; // 協程
foo的上下文,由
swapcontext
自動構造
// stack為
new/malloc
出來的也可以的
static char stack1[4096]; // 協程
zoo的棧,得合適大小,否則一樣會出現棧溢位
static char stack2[8192]; // 協程
woo的棧,得合適大小,否則一樣會出現棧溢位
int main()
printf("main 1\n");
// 構造協程
zoo的上下文
getcontext(&ctx1);
ctx1.uc_stack.ss_sp = stack1;
ctx1.uc_stack.ss_size = sizeof(stack1);
ctx1.uc_link = &ctx3; // 在
ctx1
之後的上下文
makecontext(&ctx1, zoo, 0); // 在執行完
zoo之後,執行
ctx3
// 構造協程
woo的上下文
getcontext(&ctx2);
ctx2.uc_stack.ss_sp = stack2;
ctx2.uc_stack.ss_size = sizeof(stack2);
ctx2.uc_link = &ctx1;
makecontext(&ctx2, woo, 0); // 在執行完
zoo之後,執行
ctx1
foo();
printf("main 2\n");
return 0;
// 可把
foo當成乙個執行緒,不過它是微執行緒
void foo()
printf("%s 1\n", __func__);
// 切換到
ctx2
執行,也就是執行
woo,當前的儲存在
ctx3
swapcontext(&ctx3, &ctx2);
// 當切回到
ctx3
時,會執行以下**段
printf("%s 2\n", __func__);
// 也可把
woo當成乙個執行緒,不過它是微執行緒
void woo()
printf("%s\n", __func__);
// 也可把
zoo當成乙個執行緒,不過它是微執行緒
void zoo()
printf("%s\n", __func__);
Kotlin協程快速入門
協程,全稱可以譯作協同程式,很多語言都有這個概念和具體實現,之前入門python的時候接觸過,而kotlin其實也早就有這個擴充套件功能庫了,只不過之前一直處於實驗階段,不過前段時間1.0的正式版終於出了,網上的相關部落格也多了起來,經過這幾天的學習我也來做下小結吧。首先貼下kotlin協程的官方g...
協程巢狀協程
import asyncio import functools 第三層協程 async def test1 print 我是test1 await asyncio.sleep 1 print test1已經睡了1秒 await asyncio.sleep 3 print test1又睡了3秒 ret...
9 協程 協程理論
本節的主題是基於單執行緒來實現併發,即只用乙個主線程 很明顯可利用的cpu只有乙個 情況下實現併發,為此我們需要先回顧下併發的本質 切換 儲存狀態 ps 在介紹程序理論時,提及程序的三種執行狀態,而執行緒才是執行單位,所以也可以將上圖理解為執行緒的三種狀態cpu正在執行乙個任務,會在兩種情況下切走去...