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

C++类成员condition_variable实现生产消费场景触发段错误问题求解

问题原因分析
  • 核心故障点:成员函数内创建线程的lambda使用[&]作为捕获列表,无法合法捕获当前对象的this指针。this是成员函数作用域内的纯右值,不支持引用捕获,导致lambda内调用成员函数、访问mu/cond/stored等成员变量时使用野指针,触发非法内存访问,最终出现段错误。
  • 其他引发未定义行为的问题:
    • 缺失必要标准头文件:代码使用了std::chrono时间接口、std::cin、随机数接口、时间戳接口,但未引入对应的<chrono>、<iostream>、<cstdlib>、<ctime>头文件,依赖编译器非标准的隐式头文件引入逻辑,可能触发各类未知异常。
    • 随机数初始化逻辑错误:srand()仅需全局执行一次,放在Producer函数中会被多线程同时调用,存在数据竞争,同时time(0)精度为秒,重复调用会导致随机种子被反复覆盖,生成的随机数重复。
    • 线程对象存在管理隐患:Consumer中创建的生产者调度线程pl未显式设置detach()或join(),若后续逻辑改动导致Consumer提前退出,std::thread析构时会直接调用terminate()终止程序。
修复方案
  • 所有涉及成员访问的lambda显式捕获this指针,替换原有的[&]引用捕获写法,保证成员访问的合法性。
  • 补充所有缺失的标准头文件,消除编译器依赖。
  • 将srand()初始化逻辑移到类构造函数中,仅执行一次,避免多线程竞争和重复初始化。
  • 对后台运行的调度线程显式调用detach(),消除线程对象管理隐患。
修正后完整代码
#include <thread>
#include <condition_variable>
#include <deque>
#include <chrono>
#include <iostream>
#include <cstdlib>
#include <ctime>

class Multi_Thread_Test{
public:
    std::mutex mu;
    std::condition_variable cond;
    std::deque<int> stored;

    Multi_Thread_Test(){
        // 随机种子仅初始化一次
        srand(time(0));
    }

    void Producer(){
        std::unique_lock<std::mutex> locker(mu);
        stored.push_back(rand());
        locker.unlock();
        cond.notify_one();
    }

    void Producer_loop(){
        while(true){
            // 显式捕获this指针
            std::thread t1([this]{Producer();});
            std::thread t2([this]{Producer();});
            t1.join();
            t2.join();
            std::this_thread::sleep_for(std::chrono::seconds(5));
        }
    }

    void Consumer() {
        // 显式捕获this指针,后台线程detach
        std::thread pl([this]{this->Producer_loop();});
        pl.detach();

        while (true) {
            std::unique_lock<std::mutex> locker(mu);
            cond.wait(locker, [this] { return !stored.empty(); });
            int temp = stored.front();
            stored.pop_front();
            locker.unlock();
            // 可在此处添加自定义消费逻辑
        }
    }
};

int main() {
    Multi_Thread_Test test;
    test.Consumer();
    
    std::cin.get();
    std::cin.get();
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:18:01