当前的Boost 1.55实现提供了两种unidirectional coroutines。一个是pull-type,它是一个不带参数的协程并将值返回给主上下文;另一个是push-type,它是一个从主要上下文接受参数但没有返回值的协程。
如何将这两者结合起来创建一个双向协同程序,它既接受参数又返回一个值?从表面上看,似乎应该是可能的,但我无法弄清楚如何使用boost::coroutine
中的构建块来实现它。在旧的Boosts中曾经有一个双向协程,但它现在已被弃用且没有文档,所以我不应该依赖它。
即,我想要类似于此的东西:
void accumulate( pull_func &in, push_func &out )
{
int x = 0;
while ( in )
{
x += in.get() ; // transfers control from main context
out(x); // yields control to main context
}
}
void caller( int n )
{
bidirectional_coro( accumulate );
for ( int i = 0 ; i < n ; ++i )
{
int y = accumulate(i);
printf( "%d ", y ); // "0 1 3 6 10" etc
}
}
答案 0 :(得分:6)
实际上,当它首次被包含在提升中时,提升协程是双向的(我认为是1.53)。
http://www.boost.org/doc/libs/1_53_0_beta1/libs/coroutine/doc/html/coroutine/coroutine.htm
该代码应该仍然与最新版本的boost兼容,只需稍作修改即可。
此外,您可以直接使用boost :: context来创建自己的协程类。
http://www.boost.org/doc/libs/1_55_0/libs/context/doc/html/index.html
fcontext_swap的参数'intptr_t vp'可用于来回传递值/指针,或者你可以在协程本身存储值,因为你的协程类的成员变量应该在两个上下文中都有效。
修改强>
对原始问题的简短回答是否定的。你要问的是无法做到的。每个协同程序都有自己的堆栈和上下文,无法从其他协程实例访问。此外,当你跳转到coroutine的上下文时,调用上下文的状态存储在那个 coroutine实例中,并且只能通过调用 coroutine传递给你的函数。
但是,在协程的局部范围之外声明的变量将从协程函数的内部和外部有效。所以你可以使用一个coroutine :: push_type,并推送一个指针而不是一个值。您可以使用该值,然后在跳回原始上下文之前对其进行修改。
此外,您可以安全地将指向本地变量的指针传递到协程,因为在您跳出协程并运行调用范围完成之前,它们不会被销毁。
答案 1 :(得分:1)
您可以查看boost.coroutine中包含的示例 https://github.com/boostorg/coroutine/blob/master/example/cpp03/chaining.cpp