lambda表达式 多线程安全

问题代码:

BusThreadPool::BusThreadPool(const std::map<std::string, Bus> &relationBus,
                             const std::shared_ptr<PipeManager> &pipeManager)
        : relationBusDevice(relationBus) {

    /* 初始化容器 */
    initialize();

    /* 按照母线策略分配线程 */
    for (const auto &item: relationBusDevice) {

        std::cout << "Current : " << item.first << std::endl;

        std::thread thread{[&]() {

            BusThreadExecute busThreadExecute{globalOutputSpscQueue, item.second, pipeManager};

            /* 执行计算程序 */
            busThreadExecute.execute();

        }};

        threadPool.emplace_back(std::move(thread));
    }

}

当我在线程内尝试获取item.second的成员变量时会报 Segmentation Fault。

 

问题原因:

lambda表达式的【=】和【&】语法在类内使用时会传递$this$指针,但超过此作用域后当前对象被销毁因此导致的 Segmentation Fault。

 

修复后的代码:

BusThreadPool::BusThreadPool(const std::map<std::string, Bus> &relationBus,
                             const std::shared_ptr<PipeManager> &pipeManager)
        : relationBusDevice(relationBus) {

    /* 初始化容器 */
    initialize();

    /* 按照母线策略分配线程 */
    for (const auto &item: relationBusDevice) {

        std::cout << "Current : " << item.first << std::endl;

        /* 创建线程 */
        // 显式拷贝 item 到局部变量,保留 const 属性
        const auto local_item = item.second; // 类型为 const pair<const string, Bus>

        // 显式捕获 pipeManager 的副本(共享指针)
        const std::shared_ptr<PipeManager>& local_pipe = pipeManager;

        std::shared_ptr<GlobalOutputSpscQueue> local_globalOutputSpscQueue = globalOutputSpscQueue;

        std::thread thread{[local_globalOutputSpscQueue,local_item, local_pipe]() {

            BusThreadExecute busThreadExecute{local_globalOutputSpscQueue, local_item, local_pipe};

            /* 执行计算程序 */
            busThreadExecute.execute();

        }};

        threadPool.emplace_back(std::move(thread));
    }

}
posted @ 2025-04-03 13:34  BlackSnow  阅读(21)  评论(0)    收藏  举报