寫這篇文章的原因是,很多框架/庫都有協程/纖程的支援,比如python的gevent,php 的swoole等等,但是具體是什麼樣的呢?為什麼協程方式效能會更好?很多初學者聽個詞,聽風就是雨,把協程和io能混成乙個概念。
使用纖程的第乙個步驟是將已有的執行緒轉換為乙個纖程。convertthreadtofiber這個函式會為纖程的上下文分配記憶體,這個上下文的構成是:
當我們分配了纖程執行上下文並對其進行初始化之後,還必須將執行上下文的位址與執行緒關聯起來。這樣我們就將執行緒轉換成了乙個纖程,該纖程在這個執行緒中執行。其實,除非我們打算建立更多的纖程,並讓它們在同乙個執行緒中執行,否則沒有理由將乙個執行緒轉換為纖程。
使用converthreadtofiber(ex)將當前執行緒轉換到纖程,這是纖程f1這裡說一下converthreadtofiber和converthreadtofiberex的區別
converthreadtofiber這個函式會為纖程的執行上下文分配(大約200個位元組)的記憶體,這個執行上下文由下列元素構成:
·乙個使用者自定義的值,它被初始化給converthreadtofiber的pvparam引數。
·結構化異常處理鏈的頭
·纖程棧的頂部和底部的記憶體位址(當我們將乙個執行緒轉換為乙個纖程的時候,這同時也是執行緒棧)
·某些cpu暫存器,其中包括棧指標,指令指標以及其他暫存器
預設情況下x86系統中,cpu的浮點資訊不屬於cpu暫存器的一部分,不會每個纖程都維護乙份,因此如果纖程需要執行浮點操作,那將會導致資料被破壞。
為了覆蓋系統預設的行為,我們應該呼叫新的converthreadtofiberex函式,它允許我們在dwflags引數中傳入fiber_flag_float_switch標誌
定義乙個纖程函式,用於建立乙個新纖程
纖程f1中呼叫createfiber(ex)函式建立乙個新的纖程f2
switchtofiber函式進行纖程切換,讓新建立的纖程f2執行
f2纖程函式執行完畢的時候,使用switchtofiber轉換到f1
在纖程f1中呼叫deletefiber來刪除纖程f2
纖程f1中呼叫converfibertothread,轉換為執行緒
執行緒結束
#include
"pch.h"
#include
#include
#include
#define fiber_count 2
lpvoid g_lpfiber[fiber_count]=;
void winapi fiberfun
(lpvoid pparam)
//纖程函式的返回型別為void,並不是因為返回值沒有意義,而是因為這個函式不應該返回!如果纖程函式返回,那麼該執行緒以及它所建立的所有纖程都將立即被銷毀
;_stprintf_s
(szmsg,
text
("引數1:%s, 引數2:%s。\n"
), szparam1, szparam2)
;//szparam1和szparam2一樣的
//outputdebugstring(szmsg);
std::wcout.
imbue
(std::
locale(""
, lc_ctype));
std::wcout << szmsg;
switchtofiber
(g_lpfiber[0]
);//必須切換回主線程程式才能繼續執行,不然會卡在這裡程式無法退出
}int
main()
std::cout <<
"hello world!\n"
;}
我們完全可以在io多路復用中使用協程,讓我們自己定義如何排程這些方法。 windows 纖程 fiber 實現的協程
參考雲風的協程庫實現 雲風的協程為 非對稱的共享棧協程 以下為fiber實現的非對稱協程 環境 win7 vs2013 標頭檔案 coroutine.h ifndef coroutine h define coroutine h define coroutine dead 0 define coro...
協程巢狀協程
import asyncio import functools 第三層協程 async def test1 print 我是test1 await asyncio.sleep 1 print test1已經睡了1秒 await asyncio.sleep 3 print test1又睡了3秒 ret...
纖程排程器
indy的纖程排程器排程纖程們到乙個或多個執行緒中去。纖程儲存工作專案 到乙個工作序列中然後等待。當纖程的工作專案被完成後,排程器把纖程放到乙個可以被調 度的纖程列表中。作業系統時間排程器以一種智慧型的方式排程執行緒,但是由於在系統的所有任務間每個執行緒都 是普通和泛型的 generic 它們對執行...