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

基于pthread_mutex_t、pthread_cond_t实现进程共享二元信号量的竞态问题咨询

结论

你的代码存在严重的竞态条件和多处未定义行为,无论启动顺序如何都无法稳定运行,具体问题和修复方案如下:

存在的问题

  1. 先启Pro2会直接报错退出
    如果先启动Pro2,由于Pro2调用shm_open时没有传O_CREAT标志,此时共享内存还未被Pro1创建,Pro2会直接打印错误信息退出,根本无法进入后续逻辑。

  2. 重复初始化同步对象触发未定义行为
    POSIX标准明确规定:对已经完成初始化的pthread_mutex_t、pthread_cond_t对象再次调用pthread_mutex_init/pthread_cond_init,属于未定义行为。你现在两个进程都会执行共享内存中mutex和条件变量的初始化逻辑:

  • 若Pro1还没初始化完同步对象,Pro2就已经启动并调用初始化函数,会导致同步对象状态损坏
  • 若Pro1已经初始化完成,Pro2再调用初始化函数,同样会破坏已经正常可用的同步对象,后续锁操作、条件变量操作可能出现死锁、崩溃、逻辑错误等随机问题。
  1. 未初始化就调用mutex锁操作也是未定义行为
    你在create_shm函数的create==true分支里,尝试对还未初始化的mutex调用pthread_mutex_lock修改flag,此时mutex是共享内存里的随机值,锁操作的行为完全没有任何保证。

修复方案

修改逻辑遵循核心规则:共享同步对象的初始化操作,只能由创建共享内存的进程执行一次

  1. 删掉Pro2代码中pthread_mutex_init、pthread_cond_init的所有相关逻辑,Pro2映射共享内存后直接使用同步对象即可
  2. 把Pro1中mutex、条件变量的初始化逻辑,放到create_shm调用之后、flag赋值之前,不需要对未初始化的mutex加锁,初始化完成后直接给flag赋值即可
  3. 如果你需要支持两个进程任意顺序启动,可以在共享内存结构里加一个原子类型的初始化完成标记,配合POSIX有名信号量保证只有第一个创建共享内存的进程执行初始化操作,其他进程阻塞等待初始化完成后再继续运行。

补充说明

你实现的post、wait操作逻辑本身是正确的,只要修复初始化逻辑,这个跨进程二元信号量就可以正常工作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:27:04