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

实现原子访问共享内存的pthread封装时多线程死锁问题求助

死锁根因

你的推测完全符合代码的错误逻辑,核心问题是违背了pthread_cond_wait的使用规范,触发路径如下:

  • AccessShm的GET操作执行完成后会主动释放互斥锁,返回到ThreadOne的while判断时,当前线程已经不持有shmInfo->pMutex
  • 此时调用pthread_cond_wait属于未定义行为:该函数要求调用前必须持有传入的互斥锁,你当前的调用场景完全不满足前提
  • ThreadTwo设置data为false并发送信号后,pthread_cond_wait被唤醒,会自动重新持有互斥锁再返回
  • 下一轮循环再次调用AccessShm时,函数内部会再次尝试对同一个互斥锁加锁,默认的非递归互斥锁会直接阻塞,形成死锁
修复方案

推荐采用调整加锁区间的方案,条件判断和等待操作必须放在同一个加锁区间内,这是条件变量的标准使用范式:

// ThreadOne修改为如下实现
void ThreadOne(void *arg)
{
    ShmInfo *shmInfo = (ShmInfo *) arg;
    while(1)
    {
        pthread_mutex_lock(&shmInfo->pMutex);
        // 条件判断和等待放在同一个加锁区间,避免锁状态不一致
        while(shmInfo->data == true) 
        {
          pthread_cond_wait(&shmInfo->cv, &shmInfo->pMutex); 
        }
        pthread_mutex_unlock(&shmInfo->pMutex);
        // 此处执行后续业务逻辑
    }
}

如果要保留AccessShm的封装性,也可以给函数新增参数控制是否在返回时保留锁持有状态,但需要额外注意后续手动解锁,避免漏解锁引发其他问题。

额外注意:条件变量必须配合while循环判断使用,不能替换为if判断,避免虚假唤醒导致逻辑异常,你原代码中用while的写法是正确的,只是锁的区间设计错误导致该逻辑没有发挥作用

内容的提问来源于stack exchange,提问作者xyf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 20:06:02