coroutine 协程库简介
协程有时候被称为轻量级线程,它由程序员进行调度(切换),而不像线程那样需要内核参与,同时也避免内核进行线程切换的开销。因为协程切换保留的是当前上下文环境,也就是函数调用栈和当前的寄存器,而线程切换需要陷入内核态,改变线程对象状态。
go 把协程作为基础设施提供语言级的支持,cpp 没有提供语言级的支持,而是通过准标准库 boost coroutine2 库(boost coroutine 已经废弃,建议使用 boost coroutine2)为 cpp 提供的协程支持。
协程分为对称协程(symmetric)和非对称协程(asymmetric),对称协程需要显式指定将控制权 yeild 给谁,非对称协程可以隐式的转移控制权给它的调用者,boost coroutine2 实现的是非对称协程。
push_type 和 pull_type
boost.corountine2 中的协程增加了 push_type 和 pull_type 用于提供协程数据的流转,约束了数据的从 push_type 流入,从 pull_type 流出。
当协程对象被创建之后就直接运行,直到 sink (1) 的时候暂停返回到 main 中,main 中使用 source.get () 获取数据,继续使用 source () 调用协程对象,协程从 sink (1) 之后继续运行执行完毕,返回 main,main 也执行完毕。
pull 的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <iostream> #include <boost/coroutine2/all.hpp>
void foo(boost::coroutines2::coroutine<int>::push_type & sink) { std::cout << "start coroutine\n"; sink(1); std::cout << "finish coroutine\n"; }
int main() { boost::coroutines2::coroutine<int>::pull_type source(foo); std::cout << source.get() << std::endl; //std::cout << source() << std::endl; source(); std::cout << "finish\n"; return 0; }
|
运行结果:
1 2 3 4 5 6
| lhx@ubuntu:~/boost$ g++ -o demo3 demo3.cpp -lboost_coroutine -lboost_context -L/home/lhx/boost/boost167/install/lib -I/home/lhx/boost/boost167/install/include lhx@ubuntu:~/boost$ ./demo3 start coroutine 1 finish coroutine finish
|
push 的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <iostream> #include <boost/coroutine2/all.hpp>
void foo(boost::coroutines2::coroutine<int>::pull_type& sink) { std::cout << "start coroutine\n"; //sink(); int a = sink().get(); std::cout << a << std::endl; std::cout << "finish coroutine\n"; }
int main() { boost::coroutines2::coroutine<int>::push_type source(foo); std::cout << "finish\n"; source(0); source(5); return 0; }
|
运行结果:
1 2 3 4 5 6
| lhx@ubuntu:~/boost$ g++ -o demo4 demo4.cpp -lboost_coroutine -lboost_context -L/home/lhx/boost/boost167/install/lib -I/home/lhx/boost/boost167/install/include lhx@ubuntu:~/boost$ ./demo4 finish start coroutine 5 finish coroutine
|
其他版本的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream> #include <boost/coroutine2/all.hpp>
void foo(boost::coroutines2::coroutine<void>::push_type & sink){ std::cout << "a "; sink(); std::cout << "b "; sink(); std::cout << "c "; }
int main(){ boost::coroutines2::coroutine<void>::pull_type source(foo); std::cout << "1 "; source(); std::cout << "2 "; source(); std::cout << "3 " << std::endl; return 0; }
|
运行结果:
1 2 3
| lhx@ubuntu:~/boost$ g++ -o demo1 demo1.cpp -lboost_coroutine -lboost_context -L/home/lhx/boost/boost167/install/lib -I/home/lhx/boost/boost167/install/include lhx@ubuntu:~/boost$ ./demo1 a 1 b 2 c 3
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream> #include <boost/coroutine2/all.hpp>
void foo(boost::coroutines2::coroutine<void>::pull_type & sink1){ std::cout << "a "; sink1(); std::cout << "b "; sink1(); std::cout << "c "; }
int main(){ boost::coroutines2::coroutine<void>::push_type source(foo); std::cout << "1 "; source(); std::cout << "2 "; source(); std::cout << "3 " << std::endl; return 0; }
|
运行结果:
1 2 3
| lhx@ubuntu:~/boost$ g++ -o demo2 demo2.cpp -lboost_coroutine -lboost_context -L/home/lhx/boost/boost167/install/lib -I/home/lhx/boost/boost167/install/include lhx@ubuntu:~/boost$ ./demo2 1 a 2 b 3
|