我可以用Boost 1.55构建一个双向协同程序吗

Can I build a bidirectional coroutine with Boost 1.55?

本文关键字:一个 程序 Boost 构建 我可以      更新时间:2023-10-16

当前的Boost 1.55实现提供了两种单向协程。一种是pull类型,它是一个不接受参数并向主上下文返回值的协程;另一种是push类型,它是一个从主上下文接受参数但不返回值的协程。

如何将这两者结合起来,创建一个既接受参数又返回值的双向协程?从表面上看,这似乎是可能的,但我不太清楚如何使用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
}
}

实际上,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"可以用于来回传递值/指针,也可以将值存储在协程本身中,因为协程类的成员变量在这两个上下文中都应该有效。

编辑:

对你最初的问题的简短回答是否定的。你所要求的是做不到的。每个协程都有自己的堆栈和上下文,其他协程实例无法访问这些堆栈和上下文。此外,当您跳转到协同程序的上下文时,调用上下文的状态存储在协同程序实例中,并且只能通过调用传递到函数中的参数来跳回到原始上下文。

但是,在协程局部范围之外声明的变量在协程函数内外都是有效的。因此,您可以使用协程::push_type,并推送指针而不是值。您可以使用该值,然后在跳回原始上下文之前对其进行修改。

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

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

相关文章: