Boost.Coroutine2 提供了非对称协程。
通常使用非对称协程实现生产队列
每个协程实例都有自己的栈.
与Stackless协程相比,stackful协程允许调用任意子调用栈挂起的操作,允许出入递归操作。
协程只能移动。
如果它是可复制的,那么它所有分配在栈上的对象都可以被复制。如果这些对象是RAII类,会导致不明确行为。当第一个协程拷贝终止时(栈展开),RAII类析构器会释放它管理的资源。当第二个协程拷贝终止时,同一个析构器会尝试重复释放同样的资源,导致不明确行为。
协程析构会展开相关栈。
协程的构造器允许你自定义一个栈分配器。栈分配器可自由重新分配将来使用的栈或缓存。
coroutine<>::push_type and coroutine<>::pull_type 支持分段栈 (按需增长).
通常不可能精确地估计所需的堆栈大小-在大多数情况下,会分配过多内存(浪费虚拟地址空间)。
协程构造器开始时会定义一个默认(最小)容量,这个最小的栈容量是页面大小的最大值和信号栈的典型尺寸(macro SIGSTKSZ on POSIX)。
GCC (4.7)支持 segmented stacks.
析构器释放相关栈,实施者可以自由重新分配的栈或缓存供以后使用。
context switch
协程通过每个上下文切换的底层ABI保存和恢复注册(使用 Boost.Context)。
上下文切换通过 coroutine<>::push_type::operator() and coroutine<>::pull_type::operator()完成。
Warning |
---|
Calling coroutine<>::push_type::operator() and coroutine<>::pull_type::operator() from inside the same coroutine results in undefined behaviour. |
举例,下面的代码会出现不明确行为:
boost::coroutines2::coroutine<void>::push_type coro( [&](boost::coroutines2::coroutine<void>::pull_type& yield){ yield(); }); coro();