关于co_await boost::asio::this_coro::executor返回执行器的疑问与strand切换问题
问题描述
根据boost::asio::this_coro::executor的文档说明,它是一个「返回当前协程执行器的可等待对象」。我原本认为当存在多个Executor时,co_await boost::asio::this_coro::executor应该返回协程当前运行的Executor,于是编写了测试代码:
- 在
io_context的执行器上co_spawn协程 - 随后通过
post将任务切换到switch_strand - 断言
switch_strand等于co_await boost::asio::this_coro::executor的结果
但实际结果却是最初的io_ex(io_context的执行器)等于该值。我想了解:
- 为什么会出现这种情况?
co_await boost::asio::this_coro::executor是否总是返回协程最初co_spawn的Executor,无论协程内是否切换其他Executor?- 调用带
switch_strand的post是否真的在协程内切换了Executor?
问题解答
1. boost::asio::this_coro::executor的真实作用
boost::asio::this_coro::executor返回的是协程的关联执行器——也就是你调用co_spawn时指定的执行器(若未显式指定,则默认从co_spawn的第一个参数推导)。这个关联执行器在协程创建时就固定下来,不会因为你在协程内部切换到其他执行器运行而改变。
你测试中co_await得到始终是最初io_context的执行器,这是符合设计逻辑的,并非bug。
2. post到strand未改变返回值的原因
调用post(switch_strand, ...)确实会让后续代码在switch_strand的上下文中运行——比如这段代码的执行会被strand序列化,线程安全得到保障,但这只是改变了当前代码片段的执行上下文,并没有修改协程本身的关联执行器。
举个直观的例子:你在协程里用strand的post提交了一个lambda,lambda里的代码确实在strand上运行,但协程的关联执行器还是最初的io_context执行器,this_coro::executor依然返回后者。
3. 如何获取当前执行上下文的执行器
如果你想获取当前代码正在运行的执行器(比如strand),不能用this_coro::executor,而是要通过boost::asio::get_associated_executor结合当前的completion handler,或者直接在strand上下文中引用strand对象本身。
比如在post到strand的任务里,可以这样获取当前执行器:
post(switch_strand, [&]() { auto current_exec = boost::asio::get_associated_executor(boost::asio::current_handler()); // 这里current_exec与switch_strand相等 });
内容的提问来源于stack exchange,提问作者Reizo

