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

C++11多线程生产者消费者模型竞态条件修复问题求助

问题根源

该实现存在三个核心错误:

  1. 共享变量done的修改未加锁保护,属于跨线程无锁读写的未定义行为
  2. 消费者外层循环判断逻辑错误:当生产者将done设为true后,消费者直接跳出外层循环,未处理队列中剩余的未消费元素
  3. 条件变量wait未加谓词判断,可能出现虚假唤醒导致逻辑异常

修复后的完整代码

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <queue>
using namespace std;

int main() {
    int c = 0;
    bool done = false;
    queue<int> goods;
    mutex mtx;  
    condition_variable cond_var;

    // 生产者线程
    thread producer([&]() {
        for (int i = 0; i < 500; ++i) {
            unique_lock<mutex> lock(mtx);   
            goods.push(i);
            c++;
            lock.unlock();
            cond_var.notify_one();
        }
        // 修改共享变量done必须加锁保护
        unique_lock<mutex> lock(mtx);
        done = true;
        lock.unlock();
        cond_var.notify_one();
    });

    // 消费者线程
    thread consumer([&]() {
        unique_lock<mutex> lock(mtx);
        // 循环条件调整:只要生产未结束、或队列还有未消费元素就继续运行
        while (!done || !goods.empty()) {
            // 只有队列为空时才进入等待,避免跳过未处理元素
            if (goods.empty()) {
                // wait加谓词自动过滤虚假唤醒,保证醒来时要么生产结束、要么队列有元素可处理
                cond_var.wait(lock, [&](){ return done || !goods.empty(); });
            }
            // 批量处理队列中所有可用元素
            while (!goods.empty()) {
                goods.pop();
                c--;
            }
        }
    });

    producer.join();
    consumer.join();
    cout << "Net: " << c << endl;
    return 0;
}

核心修复点说明

  1. 所有对共享变量done、goods队列、计数器c的读写操作都放在互斥锁的保护范围内,彻底消除竞态条件
  2. 调整消费者外层循环判断逻辑,保证生产者标记生产结束后,消费者依然会处理完队列中剩余的所有元素
  3. 优化条件变量等待逻辑,只有队列为空时才调用等待接口,同时通过谓词判断规避虚假唤醒问题,保证逻辑可靠性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:39:02