简体   繁体   English

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

[英]Can I build a bidirectional coroutine with Boost 1.55?

The current Boost 1.55 implementation offers two kinds of unidirectional coroutines . 目前的Boost 1.55实现提供了两种单向协同程序 One is a pull-type, which is a coroutine that takes no parameters and returns a value to the main context; 一个是pull-type,它是一个不带参数的协程并将值返回给主上下文; the other is the push-type, which is a coroutine that accepts a parameter from the main context but returns no value. 另一种是push-type,它是一个从主要上下文接受参数但没有返回值的协程。

How can I combine these two to create a bidirectional coroutine that both accepts a parameter and returns a value? 如何组合这两个来创建一个双向协程,它既接受参数又返回一个值? On the surface it seems like it should be possible, but I can't quite figure out how to do it with the building blocks I have in boost::coroutine . 从表面上看似乎应该是可能的,但是我无法弄清楚如何使用boost::coroutine的构建块来实现它。 There used to be a bidirectional coroutine in older Boosts, but it is now deprecated and undocumented, so I shouldn't rely on it. 在旧的Boosts中曾经有过双向协程,但它现在已被弃用且没有文档,因此我不应该依赖它。

ie, I would like something analogous to this: 即,我想要一些类似于此的东西:

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

Actually, boost coroutine was bidirectional when it was first included in boost(1.53 I think). 实际上,当它首次包含在boost(1.53我认为)时,提升协程是双向的。

http://www.boost.org/doc/libs/1_53_0_beta1/libs/coroutine/doc/html/coroutine/coroutine.htm http://www.boost.org/doc/libs/1_53_0_beta1/libs/coroutine/doc/html/coroutine/coroutine.htm

That code should still be compatible with the most recent version of boost, with minor modification if anything. 该代码应该仍然与最新版本的boost兼容,如果有的话,稍作修改。

Also, you could use boost::context directly to create your own coroutine class. 此外,您可以直接使用boost :: context来创建自己的coroutine类。

http://www.boost.org/doc/libs/1_55_0/libs/context/doc/html/index.html http://www.boost.org/doc/libs/1_55_0/libs/context/doc/html/index.html

The parameter 'intptr_t vp' of fcontext_swap can be use to pass values/pointers back and forth, or you could store values in the coroutine itself, as member variables of your coroutine class should be valid from both contexts. fcontext_swap的参数'intptr_t vp'可用于来回传递值/指针,或者您可以在协程本身中存储值,因为您的协程类的成员变量应该在两个上下文中都有效。

edit: 编辑:

The short answer to your original question is no. 对原始问题的简短回答是否定的。 What you are asking cannot be done. 你要问的是无法做到的。 Each coroutine has it's own stack and context, which are not accessible from other coroutine instances. 每个协同程序都有自己的堆栈和上下文,无法从其他协程实例访问。 Also, when you jump into the coroutine's context, the state of the calling context is stored in that coroutine instance, and a jump back to the original context can only be made by calling into the argument that that coroutine passed into your function. 此外,当您跳转到协同程序的上下文时,调用上下文的状态存储在协程实例中,并且只能通过调用协程传递给您的函数的参数来跳转回原始上下文。

But, variables declared outside the local scope of the coroutine will be valid from inside and outside the coroutine function. 但是,在协同程序的本地范围之外声明的变量将在协程函数内部和外部有效。 So you could use a coroutine::push_type, and push a pointer instead of a value. 所以你可以使用一个coroutine :: push_type,并推送一个指针而不是一个值。 You could use the value, and then modify it before jumping back to the original context. 您可以使用该值,然后在跳回原始上下文之前对其进行修改。

Also, you can safely pass pointers to local variables into the coroutine, since they won't be destroyed until you jump back out of the coroutine and run the calling scope to completion. 此外,您可以安全地将指向本地变量的指针传递到协程,因为它们不会被销毁,直到您跳出协程并运行调用范围完成。

你可以看一下boost.coroutine中包含的例子https://github.com/boostorg/coroutine/blob/master/example/cpp03/chaining.cpp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM