多核处理器下pthread_cond_signal唤醒多线程异常如何解决
问题根因
- 条件变量关联的共享状态
tc修改时未持有对应互斥锁:生产者线程generalThread修改全局任务计数tc时没有加锁,违反了pthread条件变量的使用规范,多核环境下会出现缓存数据不一致,导致多个被唤醒的工作线程都判断tc>0同时执行任务消费逻辑,单核环境下调度时序刚好规避了该问题。 - 互斥锁与条件变量未初始化:代码中定义的
mutexQueue、condQueue没有做静态/动态初始化,属于未定义行为,不同CPU架构下运行表现不一致。 - 共享数据缓冲区
textArr读写无同步:生产者写入缓冲区、消费者读取缓冲区的操作没有同步保护,极端情况下会出现读取到未写完的半成数据。
修复方案
- 给互斥锁和条件变量添加静态初始化,或者在main函数开头做动态初始化。
- 生产者线程修改
tc、写入textArr的逻辑,必须持有mutexQueue锁后再执行,修改完成后再调用pthread_cond_signal,最后释放锁。
修复后完整代码
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<pthread.h> #include<unistd.h> #include<time.h> pthread_attr_t attrd; // 静态初始化互斥锁和条件变量 pthread_mutex_t mutexQueue = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t condQueue = PTHREAD_COND_INITIALIZER; char textArr[128][24]; // 存储待处理随机文本的数组 int tc = 0; // 待处理任务计数 int gi = 0; // 全局数组访问游标 void *workThread(void *args){ int ai;// 内部存储当前处理的数组下标 while(1){ pthread_mutex_lock(&mutexQueue); while(tc==0){ pthread_cond_wait(&condQueue,&mutexQueue); // 无任务时等待信号 } ai=gi; gi = (gi == 127) ? 0 : gi + 1; tc--; pthread_mutex_unlock(&mutexQueue); printf("%s\n",textArr[ai]); // 后续处理websocket数据的逻辑 } } void *generalThread(void *args){ const char chrs[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // 随机文本生成字符集 int ai=0; srand(time(NULL)); while(1){ pthread_mutex_lock(&mutexQueue); for(int i=0;i<23;i++)textArr[ai][i]=chrs[rand()%61];// 模拟websocket接收数据生成随机文本 textArr[ai][23]='\0'; tc++; pthread_cond_signal(&condQueue); // 发送信号唤醒工作线程处理数据 pthread_mutex_unlock(&mutexQueue); ai = (ai == 127) ? 0 : ai + 1; // 可选:添加usleep控制生产速度,避免占满CPU // usleep(100); } } int main(int argc,char *argv[]){ pthread_attr_init(&attrd); pthread_attr_setdetachstate(&attrd,PTHREAD_CREATE_DETACHED); pthread_t gt,wt[32]; for(int i=0;i<32;i++)pthread_create(&wt[i],&attrd,&workThread,NULL); pthread_create(>,NULL,&generalThread,NULL); pthread_join(gt,NULL); return 0; }
内容的提问来源于stack exchange,提问作者BadMan
相关产品推荐
相关产品推荐

