【问题标题】:Can I build a bidirectional coroutine with Boost 1.55?我可以使用 Boost 1.55 构建双向协程吗?
【发布时间】:2013-12-20 20:31:44
【问题描述】:

当前的 Boost 1.55 实现提供了两种unidirectional coroutines。一种是拉式,是一种不带参数,返回值给主上下文的协程;另一种是push-type,它是一个从主上下文接受参数但不返回值的协程。

如何将这两者结合起来创建一个既接受参数又返回值的双向协程?从表面上看,这似乎应该是可能的,但我不太清楚如何使用我在boost::coroutine 中的构建块来做到这一点。在旧的 Boost 中曾经有一个双向协程,但它现在已被弃用且未记录在案,所以我不应该依赖它。

即,我想要类似的东西:

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
   }
}

【问题讨论】:

    标签: c++ boost coroutine


    【解决方案1】:

    实际上,boost协程在首次包含在boost(我认为是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::push_type,并推送一个指针而不是一个值。您可以使用该值,然后在跳回原始上下文之前对其进行修改。

    此外,您可以安全地将指向局部变量的指针传递给协程,因为在您跳出协程并运行调用范围完成之前,它们不会被销毁。

    【讨论】:

    • Boost 1.55 文档说双向协程代码已被弃用。 (事实上​​,这就是他们所说的全部内容;否则完全没有描述。)无论如何它们可以安全使用吗?
    • 太多的用户以错误的方式使用了双向接口——例如用户不知道何时必须将参数传递给协程的ctor,何时不。单向接口,数据流清晰。
    • @Crashworks:我不知道为什么双向协程被弃用,但我可以看到 olk 所说的可能是真的。它使用起来可能是安全的,但它没有得到维护,因此您必须自己修复发现的任何新错误。另外,请参阅我的编辑以获取更多详细信息,为什么您所要求的内容不起作用,以及建议的解决方法。
    • 我接受这个答案为“不。你不能用boost::coroutine 做到这一点。但是,你可以用 boost::context 构建你自己的东西来完成你需要的东西。 "
    • 此评论似乎暗示我的回答包含不正确的信息。如果是这样,请告诉我,以便我更正。
    【解决方案2】:

    您可以查看 boost.coroutine 中包含的示例 https://github.com/boostorg/coroutine/blob/master/example/cpp03/chaining.cpp

    【讨论】:

    • 这不完全一样——这个例子展示了一个拉协程如何反过来调用另一个拉协程进行输入。我正在寻找的是一种让一个协程同时拉取和推送到相同上下文的方法。
    • 如果您不能根据需要调整示例,那么我不得不说这是不可能的。唯一的方法是传递一个能够存储 coroutine-fn 的引用或指针的参数。
    猜你喜欢
    • 2013-12-14
    • 2011-01-24
    • 2014-09-08
    • 2016-03-15
    • 2014-03-20
    • 2014-02-11
    • 2016-03-21
    • 1970-01-01
    • 2014-03-02
    相关资源
    最近更新 更多