C/C++協程的實現方式總結

一、利用 C 語言的 setjmp 和 longjmp,函數中使用 static local 的變量來保存協程內部的數據。html

函數原型:int setjmp(jmp_buf envbuf);git

     void longjmp(jmp_buf envbuf, int val);github

先調用setjmp,用變量envbuf記錄當前的位置,而後調用longjmp,返回envbuf所記錄的位置,並使setjmp的返回值爲val。使用longjmp後,envbuf的內容會被銷燬。編程

一個例子(引自《C專家編程》):函數

 1 #include <stdio.h> 
 2 #include <setjmp.h>
 3  
 4 jmp_buf buf;  5 
 6 banana()  7 {  8     printf("in banana() \n");  9     longjmp(buf,1); 10     printf("you'll never see this,because i longjmp'd"); 11 } 12 
13 main() 14 { 15     if(setjmp(buf)) 16         printf("back in main\n"); 17     else
18  { 19         printf("first time through\n"); 20  banana(); 21  } 22 }

打印結果:this

first time throughlua

in banana()spa

back in main操作系統

 

二、利用C語言語法switch-case的技巧來實現(Protothreads) 。線程

設置一個標識符,改變標識符的值,經過switch-case對標識符值的判斷操縱各協程函數輪流執行。

每一個協程函數可配一個結構體,保存棧內容和狀態機。

代碼:https://github.com/georgeredinger/protothreads

 

三、使用匯編代碼來切換上下文(實現c協程) 。

構建一個結構體保存棧內容和當前位置等上下文信息,利用匯編語言的跳轉實現協程功能。

詳情見:https://www.cnblogs.com/heluan/p/9899824.html

 

四、利用操做系統提供的接口:Linux的ucontext,Windows的Fiber。(雲風的coroutine)

ucontext: makecontext()       建立上下文      

      getcontext()         讀取上下文

      setcontext()         設置上下文

      swapcontext()        跳轉上下文

Fiber(纖程):ConverThreadToFiber()     從當前線程進入纖程

      CreateFiber()         建立新纖程

      SwitchToFiber()        切換到纖程

      DeleteFiber()          刪除纖程

                    若是刪除當前纖程,會致使它所在的線程退出 

操做系統的接口函數自己,提供了保存棧內容的功能。

相關文章
相關標籤/搜索