pthread_cond_signal()无法唤醒等待线程问题咨询
pthread_cond_wait永久阻塞无法返回的原因
核心机制前提
pthread_cond_wait不是收到信号就会立刻返回,它的内部执行逻辑是原子完成以下三个步骤:
- 调用时自动释放传入的关联互斥锁,将当前线程加入条件变量的等待队列
- 阻塞等待条件变量的唤醒通知
- 收到唤醒通知后,必须重新成功获取到关联的互斥锁,才会真正从函数返回;如果锁被其他线程持有,会持续阻塞等待锁释放。
代码死锁原因
逐行对应运行流程即可定位问题:
- producer线程先启动,成功获取
_mutex锁,打印producer wait() begins后调用pthread_cond_wait,此时函数自动释放_mutex锁,producer进入等待信号的阻塞状态。 - consumer线程sleep1秒后尝试获取
_mutex锁,因为锁已经被producer在wait阶段释放,consumer成功拿锁,依次打印consumer wait for lock、consumer signals,随后调用pthread_cond_signal向等待队列发唤醒信号。 - 关键错误点:consumer发完信号后,全程没有释放持有的
_mutex锁:先是执行sleep(2)持有锁休眠2秒,休眠结束后直接退出线程,始终没有调用pthread_mutex_unlock解锁。 - 最终结果:producer收到唤醒信号后,尝试重新获取
_mutex锁,但锁一直被consumer持有,consumer退出后也没有解锁,锁进入永久不可获取的死锁状态,producer永远拿不到锁,自然无法从pthread_cond_wait返回,也就永远打印不出producer wait() ends。
修正方案
只需要在consumer线程发送信号后,及时释放互斥锁即可,修正后的consumer逻辑如下:
void* consumer(void*) { sleep(1); printf("consumer wait for lock\n"); pthread_mutex_lock(&_mutex); printf("consumer signals\n"); pthread_cond_signal(&_cond); pthread_mutex_unlock(&_mutex); // 发送信号后及时释放关联互斥锁 sleep(2); return NULL; }
另外补充一个兼容性问题:全局互斥锁和条件变量的初始化写法不标准,标准POSIX写法需要加等号:
pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t _cond = PTHREAD_COND_INITIALIZER;
内容的提问来源于stack exchange,提问作者gongliming7
相关产品推荐
相关产品推荐

