一、利用 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() 刪除纖程
若是刪除當前纖程,會致使它所在的線程退出
操做系統的接口函數自己,提供了保存棧內容的功能。