立即启动协程 C++ asio

问题描述 投票:0回答:1

使用预协程 asio 接口时,我可以立即分派异步函数并让它在上下文中完成。

asio::dispatch([](){
    // executes immediately
    asio::steady_timer t(ctx, 2s);
    t.async_wait([](){
        // executes in ctx.run()
    });
});
ctx.run()

我想用

asio::awaitable
复制这个,但是 dispatch 不支持协程。

asio::dispatch([]() -> asio::awaitable<void> { // can't dispatch coroutine directly
    // should execute immediately
    asio::steady_timer t(ctx, 2s);
    co_await t.async_wait(asio::use_awaitable);
    // should execute in ctx.run()
    co_return;
});
ctx.run()

另一方面

asio::co_spawn
只是将协程添加到上下文中,并没有立即启动它。

我可以使用

ctx.poll()
/
ctx.run_one()
但协程必须是唯一准备执行的,或者至少是第一个。

c++ boost-asio
1个回答
1
投票

此代码有多种方式无法执行它建议的/您描述的将执行的操作:

asio::dispatch([](){
    // executes immediately
    asio::steady_timer t(ctx, 2s);
    t.async_wait([](){
        // executes in ctx.run()
    });
});
ctx.run();
  • 它永远不会等待2秒,因为t

    的析构函数会在启动后立即取消
    async_await

  • ctx

    显然是静态的或全局的,因为它没有被捕获

  • 完成处理程序没有所需的签名

  • 即使它确实正确地接受了一个

    error_code

     变量,它也不会
    “在 ctx.run() 中执行 [s]” 因为 dispatch
     在 lambda 的
    关联执行器 上调度。这,因为没有其他关联,将默认为 asio::system_executor
    .
    的默认构造实例

    参见例如

    std::boost::asio::post / dispatch 使用哪个 io_context?

Q. 另一方面,asio::co_spawn 只将协程添加到上下文中,不会立即启动它。

我认为这也不准确。正如您提到的那样,您提供的代码无效(因为

post

 不支持协程)。当固定使用
co_spawn
时,我们可以显示它在里面运行
ctx.run()

#include <boost/asio.hpp> #include <iostream> namespace asio = boost::asio; using namespace std::chrono_literals; int main() { asio::io_context ctx; asio::co_spawn( ctx, []() -> asio::awaitable<void> { auto ex = co_await asio::this_coro::executor; asio::steady_timer t(ex, 2s); co_await t.async_wait(asio::use_awaitable); std::cout << "inside ctx.run()" << std::endl; // co_return; }, asio::detached); std::cout << "before ctx.run()" << std::endl; ctx.run(); std::cout << "after ctx.run()" << std::endl; }
打印

我真的认为99%的问题都取决于这些错误的前提,所以我在阐述之前等待你的反应。

© www.soinside.com 2019 - 2024. All rights reserved.