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

pthread_cond_signal()无法唤醒等待线程问题咨询

pthread_cond_wait永久阻塞无法返回的原因

核心机制前提

pthread_cond_wait不是收到信号就会立刻返回,它的内部执行逻辑是原子完成以下三个步骤:

  1. 调用时自动释放传入的关联互斥锁,将当前线程加入条件变量的等待队列
  2. 阻塞等待条件变量的唤醒通知
  3. 收到唤醒通知后,必须重新成功获取到关联的互斥锁,才会真正从函数返回;如果锁被其他线程持有,会持续阻塞等待锁释放。

代码死锁原因

逐行对应运行流程即可定位问题:

  • 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:57:23