Boost Asio:如何在多个独立Strand中运行单个处理函数?
问题
在多线程场景下,我们拥有三个及以上独立Strand,每个Strand分别序列化访问不同资源,对应代码如下:
boost::asio::io_context ioc; auto io_ex = ioc.get_executor(); auto strand_a = boost::asio::make_strand(io_ex); auto strand_b = boost::asio::make_strand(io_ex); auto strand_c = boost::asio::make_strand(io_ex); // TODO: 将处理函数调度到所有三个Strand上 std::jthread threads[3]; // 提供足够线程以并行处理Strand for (auto& thread : threads) thread = std::jthread{ [&]() { ioc.run(); }};
需要实现让单个处理函数同时在所有Strand中运行,从而能在该处理函数内安全地同时访问所有资源,最终需确保该处理函数内以下表达式结果为true:
strand_a.running_in_this_thread() && strand_b.running_in_this_thread() && strand_c.running_in_this_thread()
解决方案
核心思路是通过Strand嵌套调度,让任务依次进入每个目标Strand的执行上下文,最终在所有Strand的上下文中执行处理函数。
完整实现代码
#include <boost/asio.hpp> #include <thread> #include <cassert> int main() { boost::asio::io_context ioc; auto io_ex = ioc.get_executor(); auto strand_a = boost::asio::make_strand(io_ex); auto strand_b = boost::asio::make_strand(io_ex); auto strand_c = boost::asio::make_strand(io_ex); // 目标处理函数:可安全访问所有Strand对应的资源 auto process_all_resources = [&]() { // 验证是否处于所有Strand的执行上下文 bool in_all_strands = strand_a.running_in_this_thread() && strand_b.running_in_this_thread() && strand_c.running_in_this_thread(); assert(in_all_strands); // 确保条件成立 // 此处编写资源访问逻辑 }; // 链式嵌套调度:依次进入每个Strand的上下文 boost::asio::post(strand_a, [&]() { boost::asio::post(strand_b, [&]() { boost::asio::post(strand_c, process_all_resources); }); }); std::jthread threads[3]; for (auto& thread : threads) { thread = std::jthread{[&]() { ioc.run(); }}; } }
原理说明
- Boost.Asio的Strand保证提交到它的任务串行执行,
running_in_this_thread()仅当当前线程正在执行该Strand调度的任务时返回true。 - 嵌套调度让任务依次进入每个Strand的执行队列:当处理函数在
strand_c中执行时,它的调用栈已经处于strand_a和strand_b的任务上下文内,因此三个running_in_this_thread()都会返回true。 - 这种方式本质上是让处理函数处于所有Strand的串行执行链末端,自然继承了所有上游Strand的上下文标记。
内容的提问来源于stack exchange,提问作者Reizo
相关产品推荐
相关产品推荐

