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

不使用pthread库的C++生产者消费者程序无大写输出问题排查

问题核心原因
  • 同步状态变量为局部变量:produce和consume函数内部的count是栈上临时变量,每次调用都会初始化为0,无法在线程之间共享同步状态。生产者的count++不会对消费者的判断产生任何影响,消费者永远会卡在cv.wait(lck)这一行,不会执行打印大写字母的逻辑,这是没有大写输出的直接原因。
  • 线程逻辑缺少同步规则:多个生产者同时写入全局缓冲区会导致数据覆盖,也没有控制生产和消费的执行顺序,无法实现「生产一批→消费一批」的预期逻辑。
  • 条件变量使用不规范:未处理虚假唤醒场景,可能出现逻辑异常。
修正代码
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <random>
#include <cmath>
#include <cctype>
using namespace std;

mutex mtx;
condition_variable cv;
const int BATCH_NUM = 3; // 生产消费总轮次,和你预期输出的3轮对应

int buff_size = 0;
char* buff;
int buffer_ready = 0; // 全局同步标记:1表示缓冲区有未消费数据,0表示可生产

int random_int(int lower_bound) {
    random_device seed;
    mt19937 generator(seed());
    uniform_int_distribution<int> dist(lower_bound, nextafter(26, DBL_MAX));
    return dist(generator);
}

char random_char(int lower_bound) {
    return 'A' + (random_int(lower_bound) % 26);
}

// 消费者
void consume(int job) {
    unique_lock<mutex> lck(mtx);
    // 带谓词的wait,自动处理虚假唤醒
    cv.wait(lck, []{ return buffer_ready == 1; });
    for (int i = 0; i < buff_size; i++) {
        cout << buff[i] << endl;
    }
    buffer_ready = 0;
    cv.notify_one(); // 通知生产者可以继续生产
}

// 生产者
void produce(int job) {
    unique_lock<mutex> lck(mtx);
    cv.wait(lck, []{ return buffer_ready == 0; });
    for (int i = 0; i < buff_size; i++) {
        buff[i] = random_char(buff_size);
        cout << static_cast<char>(tolower(buff[i])) << endl;
    }
    buffer_ready = 1;
    cv.notify_one(); // 通知消费者可以消费
}

int main() {
    int buf_size = 0;
    cout << "The Process-Producer Problem" << endl;
    cout << "Enter the buffer size: ";
    cin >> buf_size;

    if (buf_size > 0 && buf_size <= 26) {
        buff_size = buf_size;
        buff = new char[buff_size];
    }
    else {
        exit(1);
    }

    thread production[BATCH_NUM], processed[BATCH_NUM];
    // 初始化线程
    for (int order = 0; order < BATCH_NUM; order++) {
        production[order] = thread(produce, order);
        processed[order] = thread(consume, order);
    }

    // 等待线程执行完成,先等生产者再等消费者避免死锁
    for (int order = 0; order < BATCH_NUM; order++) {
        production[order].join();
        processed[order].join();
    }

    delete[] buff;
    cout << "InterProcess Communication is completed. " << endl;
    return 0;
}
补充说明
  • 新增全局buffer_ready作为同步标记,生产者和消费者通过这个标记判断是否可以执行自身逻辑
  • 条件变量使用带谓词的重载版本,避免虚假唤醒导致的逻辑错误
  • 调整了线程创建和join的逻辑,符合预期的3轮生产消费流程
  • 补充了缺失的头文件,避免编译错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:18:01