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

多线程不同间隔调用方法时,共享boost::asio::io_context是否安全?

关于多线程共享boost::asio::io_context的安全性

完全可以安全地在多线程场景下共享同一个boost::asio::io_context。Boost Asio的核心设计就支持这种用法:io_context本身是线程安全的,多个线程可以同时调用它的run()、run_one()或poll()系列方法,异步任务会被自动分发到各个线程中执行,无需额外的同步措施(只要你的回调函数本身是线程安全的)。

不过你的示例代码存在不少问题,会导致逻辑错误甚至崩溃,需要修正:

  • io_context成员矛盾:你的Myclass构造函数接收外部io_context的引用,但私有成员又定义了一个自己的io_context_,这会导致实际使用的是类内部的io_context,而非你想要共享的外部实例。应该把私有成员改为boost::asio::io_context& io_context_;(注意是引用,需要确保外部io_context的生命周期长于Myclass)。

  • 悬垂引用与内存问题:

    • 在start_method_thread中,std::unique_ptr<TestTimerContext>是局部变量,函数结束后会被销毁,而async_wait的lambda捕获了&ctx_ref,这会导致timer被销毁,回调触发时引用无效,直接崩溃。
    • func_cb中使用的Arc<TestTimerContext>(应为std::shared_ptr)构造方式错误,且lambda同样捕获了局部变量的引用,同样会导致悬垂。正确的做法是用shared_ptr持有TestTimerContext,并在lambda中捕获shared_ptr的拷贝,保证timer的生命周期覆盖整个异步操作。
  • 未运行io_context事件循环:你的代码只发起了异步wait操作,但没有任何线程调用io_context_.run(),这意味着所有异步回调永远不会被执行。正确的做法是:要么在外部启动多个线程运行共享的io_context的run方法,要么在合适的线程中调用io_context_.run()(多个线程调用run时,io_context会自动做负载均衡)。

  • 线程join的逻辑问题:start_process中创建线程后立即join,会导致主线程被阻塞,且每个线程的任务只是发起异步操作,没有实际运行事件循环,完全失去了多线程的意义。

  • 其他拼写与语法错误:代码中存在methdo2、condistions、end(应为endl)等拼写错误,还有重复声明的method1函数,这些都需要修正。

修正后的核心思路示例

#include <boost/asio.hpp>
#include <memory>
#include <thread>
#include <vector>
#include <iostream>

using namespace boost::asio;

struct TestTimerContext {
    steady_timer timer;
    TestTimerContext(io_context& io) : timer(io) {}
};

enum MethodTypes { FIRST = 0, SECOND = 1, THIRD = 2 };

class Myclass {
public:
    // 保存外部io_context的引用
    Myclass(io_context& io) : io_context_(io) {}
    
    void start_process(const std::vector<bool>& conditions, const std::vector<uint32_t>& intervals);

private:
    io_context& io_context_;
    
    void start_timer(uint32_t interval, MethodTypes method_type);
    void func_cb(const boost::system::error_code& err, std::shared_ptr<TestTimerContext> ctx, uint32_t interval, MethodTypes method_type);
    
    void method1();
    void method2();
    void method3();
};

void Myclass::start_process(const std::vector<bool>& conditions, const std::vector<uint32_t>& intervals) {
    if (conditions.size() > FIRST && conditions[FIRST]) {
        start_timer(intervals[FIRST], FIRST);
    }
    if (conditions.size() > SECOND && conditions[SECOND]) {
        start_timer(intervals[SECOND], SECOND);
    }
    if (conditions.size() > THIRD && conditions[THIRD]) {
        start_timer(intervals[THIRD], THIRD);
    }
}

void Myclass::start_timer(uint32_t interval, MethodTypes method_type) {
    auto ctx = std::make_shared<TestTimerContext>(io_context_);
    
    if (interval == 0) {
        func_cb({}, ctx, interval, method_type);
        return;
    }
    
    ctx->timer.expires_after(std::chrono::milliseconds(interval));
    // 捕获ctx的拷贝,保证生命周期
    ctx->timer.async_wait([this, ctx, interval, method_type](const boost::system::error_code& err) {
        func_cb(err, ctx, interval, method_type);
    });
}

void Myclass::func_cb(const boost::system::error_code& err, std::shared_ptr<TestTimerContext> ctx, uint32_t interval, MethodTypes method_type) {
    if (err) {
        std::cout << "cb function has an error: " << err.message() << std::endl;
        return;
    }

    switch (method_type) {
        case FIRST: method1(); break;
        case SECOND: method2(); break;
        case THIRD: method3(); break;
        default: std::cout << "method type is not supported" << std::endl; return;
    }

    if (interval == 0) {
        return;
    }
    
    // 重新设置定时器,继续循环
    ctx->timer.expires_after(std::chrono::milliseconds(interval));
    ctx->timer.async_wait([this, ctx, interval, method_type](const boost::system::error_code& err) {
        func_cb(err, ctx, interval, method_type);
    });
}

void Myclass::method1() {
    std::cout << "method1 is called!" << std::endl;
}

void Myclass::method2() {
    std::cout << "method2 is called!" << std::endl;
}

void Myclass::method3() {
    std::cout << "method3 is called!" << std::endl;
}

// 外部使用示例
int main() {
    io_context io;
    
    // 启动多个线程运行io_context的事件循环,实现多线程处理异步任务
    std::vector<std::thread> threads;
    for (size_t i = 0; i < 3; ++i) {
        threads.emplace_back([&io]() {
            io.run();
        });
    }
    
    Myclass obj(io);
    obj.start_process({true, true, true}, {1000, 2000, 3000});
    
    // 等待所有线程结束(实际场景中可能需要信号处理来优雅停止)
    for (auto& t : threads) {
        t.join();
    }
    
    return 0;
}

内容的提问来源于stack exchange,提问作者Ashkanxy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:00:56