【问题标题】:How to make C++ async programming more linear (coroutines?)如何使 C++ 异步编程更线性(协程?)
【发布时间】:2017-07-26 11:42:40
【问题描述】:

在 C++14 中,我想构建一种机制,使用 单线程,以“顺序”方式使用异步 API。

更明确地说,我想实现这样的目标:

// Transform AsyncOp1 into SyncOp1
// SyncOp1 returns after AsyncOp1 completes
// but yields execution to another script
void SyncOp1()
{
    AsyncOp1( [](){ // async op completion handler
        // TODO: yield control
    } );
    // TODO: control returns here after AsyncOp1 completed
}

... // similar code for SyncOp2, SyncOp3, SyncOp4,...

void Script1()
{
    SyncOp1(); 
    SyncOp2(); // SyncOp2 starts only after AsyncOp1 has completed
    ...
}

void Script2()
{
    SyncOp3(); 
    SyncOp4(); // SyncOp4 starts only after AsyncOp3 has completed
    ...
}

int main()
{
    ...
    Spawn( Script1 );
    Spawn( Script2 ); // Script1 and Script2 runs in parallel
    ...
    // TODO some machinery here :-)
    ...
    return 0;
}

我的程序应该同时运行多个脚本,每个脚本应该是一系列标准函数调用 (SyncOpX)。这些脚本可以并行运行,因为SyncOpX 是根据异步函数(即,在 I/O 完成时启动 I/O 操作、返回和调用回调的函数)实现的。

当然,使用多线程很容易找到解决方案(Spawn 创建一个新线程,SynchOpX 等待异步调用的结果)。但我正在寻找一个单线程解决方案,而不是。

我认为协程可以以某种方式使用。既然目前的标准是C++14,有boost coroutines的解决方案吗?还是使用任何其他 [便携式] 机制?

顺便说一句:我将 boost::asio 用于异步 I/O。

谢谢。

【问题讨论】:

  • 您是否正在考虑使用 libuvlibevent 之类的库?
  • @j2ko 我已经在使用 boost::asio 来处理 I/O 异步事件。我正在寻找的是一种 C++ 机制,可以使异步编程更具顺序性(无线程)。

标签: asynchronous c++14 coroutine boost-coroutine boost-coroutine2


【解决方案1】:

如果你已经使用 boost.asio,你应该考虑它的 spawn() 和 yield_context - http://www.boost.org/doc/libs/1_63_0/doc/html/boost_asio/reference.html#boost_asio.reference.spawn

另外你可以考虑 boost.fiber:

“Boost.Fiber 的主要优点之一是能够使用异步操作来提高效率,同时将调用代码结构化,就好像操作是同步的一样。”

【讨论】: