boost 协程库 coroutine 介绍

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