快速上手,協程剖析

2021-06-22 14:17:34 字數 2529 閱讀 3928

協程也叫微執行緒,英文名稱為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正在執行乙個任務,會在兩種情況下切走去...