boost.coroutine學習筆記
blog中的文章地址:http://www.godebug.org/index.php/archives/124/
boost.coroutine庫是一個stackfull的coroutine,其實本來對這東西沒啥太大興趣,不過後來發現boost.asio對這玩意有個封裝,而且用起來很爽,比我之前寫文章介紹的那個stackless的coroutine強大太多,再加上好久沒寫部落格了,今天就寫點吧。
不廢話了上程式碼:
#include <iostream>
#include <boost/coroutine/all.hpp>
typedef boost::coroutines::asymmetric_coroutine< void >::pull_type pull_coro_t;
typedef boost::coroutines::asymmetric_coroutine< void >::push_type push_coro_t;
void foo(push_coro_t & sink)
{
std::cout << "1";
sink();
std::cout << "2";
sink();
std::cout << "3";
sink();
std::cout << "4";
}
int main(int argc, char * argv[])
{
{
pull_coro_t source(foo);
while (source)
{
std::cout << "-";
source();
}
}
std::cout << "\nDone" << std::endl;
return 0;
}
執行輸出:
1-2-3-4
Done
很好理解,當呼叫source的時候進入foo函式,當在foo中呼叫sink的時候就返回到呼叫source的地方,重複呼叫source會多次進入foo函式,每次從上次呼叫sink的下一句開始執行。這些跟那個stackless的coroutine沒啥太大不同,但是不同的是stackless的coroutine不能在reenter中使用區域性變數,即使加個大括號可以使用區域性變數,再次進入函式的時候變數的值也會丟失,而stackfull的則不會。這就帶來了很大的方便。 不過上面的程式碼中的foo沒有返回值,很多時候我們需要從coroutine中返回東西,假設foo需要返回一個int,這時候程式碼需要改成下面這樣:
#include <iostream>
#include <boost/coroutine/all.hpp>
typedef boost::coroutines::asymmetric_coroutine< int >::pull_type pull_coro_t;
typedef boost::coroutines::asymmetric_coroutine< int >::push_type push_coro_t;
void runit(push_coro_t & sink1)
{
std::cout << "1" << std::endl;
sink1(10);
std::cout << "2" << std::endl;
sink1(20);
std::cout << "3" << std::endl;
sink1(30);
std::cout << "4" << std::endl;
}
int main(int argc, char * argv[])
{
{
pull_coro_t source(runit);
while (source)
{
int ret = source.get();
std::cout << "ret: " << ret << std::endl;
source();
}
}
std::cout << "\nDone" << std::endl;
return 0;
}
執行輸出:
1
ret: 10
2
ret: 20
3
ret: 30
4
Done
太簡單了,不解釋了。。對照沒有返回值的程式碼看看那裡改了就一目瞭然。
不過光有返回值不行,還得有引數:
#include <iostream>
#include <boost/coroutine/all.hpp>
typedef boost::coroutines::asymmetric_coroutine< int >::pull_type pull_coro_t;
typedef boost::coroutines::asymmetric_coroutine< int >::push_type push_coro_t;
void runit(pull_coro_t & source)
{
std::cout << source.get();
source();
std::cout << source.get();
source();
std::cout << source.get();
source();
std::cout << source.get();
}
int main(int argc, char * argv[])
{
{
push_coro_t sink(runit);
int i = 0;
while (sink)
{
++i;
sink(i);
std::cout << "-";
}
}
std::cout << "\nDone" << std::endl;
return 0;
}
執行輸出:
1-2-3-4- Done
其實就是把pull和push給對調了一下,把引數push給被呼叫的函式,不過好像沒法同時傳多個引數,也不能同時有引數和返回值(至少我在他的example中沒找到,有知道的希望能不吝賜教),應該可以用tuple和返回引數解決,不想測試了。pull和push除了一個是接收引數一個是返回之外,還有點差別,pull在構造的時候就會呼叫傳遞給他的函式,push不會,判斷呼叫都完成了沒有也有一定的差別。不過懶得管他了反正最後要用的是asio封裝的coroutine,這個只是瞭解一下
本來還打算看看這個coroutine咋實現的,結果發現他是自己用匯編實現了底層細節,自己從FS暫存器中讀取了執行緒環境塊(TEB)和SEH鏈神馬的處理了,然後就是記錄呼叫push和pull函式的地址,以及各種jmp跳轉往返於push和pull之間。有點略複雜,就沒詳細看。
over
相關文章
- numpy的學習筆記\pandas學習筆記筆記
- IT學習筆記筆記
- 學習筆記筆記
- 【學習筆記】數學筆記
- 《JAVA學習指南》學習筆記Java筆記
- Elasticsearch學習筆記Elasticsearch筆記
- Scala學習筆記筆記
- MySql學習筆記MySql筆記
- jQuery 學習筆記jQuery筆記
- react學習筆記React筆記
- 學習筆記(4.3)筆記
- 學習筆記(4.4)筆記
- 學習筆記(3.29)筆記
- 學習筆記(4.1)筆記
- AOP學習筆記筆記
- AspectJ學習筆記筆記
- 學習筆記(3.27)筆記
- 學習筆記(4.2)筆記
- golang 學習筆記Golang筆記
- Zookeeper學習筆記筆記
- 學習筆記(3.24)筆記
- 學習筆記(3.25)筆記
- 學習筆記(3.21)筆記
- GitHub學習筆記Github筆記
- jest 學習筆記筆記
- typescript 學習筆記TypeScript筆記
- Echarts學習筆記Echarts筆記
- js學習筆記JS筆記
- shell學習筆記筆記
- Dubbo 學習筆記筆記
- SVN 學習筆記筆記
- 笨笨學習筆記筆記
- vue學習筆記Vue筆記
- wepack學習筆記筆記
- redis學習筆記Redis筆記
- java學習筆記Java筆記
- PureMVC學習筆記REMMVC筆記
- gitee 學習筆記Gitee筆記