如何在C++ Asio中基于awaitable实现协程立即启动?
使用Asio协程复刻dispatch的立即执行行为
在Asio协程特性出现前,我们可以在当前执行上下文(比如main函数)中通过dispatch调度异步函数,让它在指定的io_context中完成,示例代码及运行结果如下:
#include <iostream> #include <asio.hpp> using namespace std; using namespace literals; int main() { asio::io_context ctx; asio::steady_timer t(ctx, 2s); asio::dispatch([&](){ cout << "inside coro before wait" << endl; t.async_wait([](asio::error_code){ cout << "inside coro after wait" << endl; }); }); cout << "starting ctx.run()" << endl; ctx.run(); }
运行结果:
$ ./sol inside coro before wait starting ctx.run() inside coro after wait
我希望用asio::awaitable复刻这一行为,但遇到了问题:dispatch不支持协程;co_spawn仅会把协程添加到上下文,不会立即启动它;使用ctx.poll()/ctx.run_one()又存在执行顺序上的限制。
解决方法
要从协程外部启动协程,唯一的方式是使用asio::co_spawn(executor, awaitable, token)。和dispatch不同,co_spawn需要接收一个执行器作为参数,而dispatch依赖的是关联执行器。因此,要让协程立即启动,我们需要指定在asio::system_executor()中运行它,示例代码及运行结果如下:
#include <bits/stdc++.h> #include <asio.hpp> using namespace std; using namespace literals; int main() { asio::io_context ctx; asio::co_spawn(asio::system_executor(), [&]() -> asio::awaitable<void> { cout << "inside coro before wait" << endl; asio::steady_timer t(ctx, 2s); co_await t.async_wait(asio::use_awaitable); cout << "inside coro after wait" << endl; co_return; }, asio::detached); cout << "starting ctx.run()" << endl; ctx.run(); }
运行结果:
$ ./sol inside coro before wait starting ctx.run() inside coro after wait
内容的提问来源于stack exchange,提问作者Tellegar
相关产品推荐
相关产品推荐

