不使用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
相关产品推荐
相关产品推荐

