我可以使用Boost 1.55构建双向协程吗?

时间:2013-12-20 20:31:44

标签: c++ boost coroutine

当前的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
   }
}

2 个答案:

答案 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