You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:32:39