C语言pthread并行编程 单生产者单消费者程序性能问题咨询
代码问题分析与优化建议
你的生产者消费者实现存在多处可优化和逻辑漏洞点,具体如下:
- 缺少条件变量等待谓词,存在虚假唤醒风险
POSIX标准规定pthread_cond_wait()允许无触发的虚假唤醒,你的代码未对等待条件做二次校验,一旦出现虚假唤醒,生产者会在队列已满时继续写入,消费者会在队列为空时读取queue[-1],触发数组越界的未定义行为,严重时会直接崩溃。 - 临界区粒度过大,存在不必要的性能损耗
随机数生成逻辑rand() % 100不需要放在互斥锁保护范围内,你可以在加锁前完成随机数计算,仅在操作共享队列、计数器时持有锁,减少锁持有时间,提升并发效率。 - 无队列边界校验,逻辑健壮性不足
你的队列长度仅为1,却没有针对queueCounter的边界判断,后续如果修改NUM_THREAD开启多生产者/多消费者,会直接出现越界读写问题。 - 存在冗余头文件引用
代码中引用了<semaphore.h>和自定义头文件produceConsume.h,但整段逻辑没有用到这两个头文件的任何定义,属于无效引用,可以直接删除。
优化后参考实现
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <pthread.h> #include <time.h> #define NUM_THREAD 1 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int queue[1]; int queueCounter = 0; void *producer(void *args) { while (1) { // 随机数生成放在锁外,减少锁持有时间 int n = rand() % 100; pthread_mutex_lock(&lock); // 用while循环做谓词判断,应对虚假唤醒 while (queueCounter != 0) { pthread_cond_wait(&cond, &lock); } queue[0] = n; queueCounter = 1; pthread_cond_signal(&cond); pthread_mutex_unlock(&lock); } } void *consumer(void *args) { while (1) { pthread_mutex_lock(&lock); while (queueCounter != 1) { pthread_cond_wait(&cond, &lock); } int num = queue[0]; queueCounter = 0; pthread_cond_signal(&cond); pthread_mutex_unlock(&lock); // 打印、休眠逻辑放在锁外,避免占用锁资源 printf("%d\n", num); sleep(1); } } int main() { system("clear"); srand(time(NULL)); pthread_t th[NUM_THREAD], th2[NUM_THREAD]; for (int i = 0; i < NUM_THREAD; i++) { pthread_create(&th[i], NULL, &producer, NULL); pthread_create(&th2[i], NULL, &consumer, NULL); } for (int i = 0; i < NUM_THREAD; i++) { pthread_join(th[i], NULL); pthread_join(th2[i], NULL); } return 0; }
额外优化提示
如果后续要扩展为多生产者/多消费者模式,建议:
- 替换非线程安全的
rand()为线程安全的rand_r()或其他随机数生成实现 - 调整队列长度为更大的值,匹配生产者和消费者的处理速度差,提升整体吞吐量
内容的提问来源于stack exchange,提问作者user16984278
相关产品推荐
相关产品推荐

