主线程触发pthread子线程执行操作的可靠方案,可否不使用互斥锁?
结论:该实现不稳健,不能省略同步机制
这种无锁的跨线程共享变量访问方式存在多个风险,完全无法保证运行正确性,不建议在生产环境使用:
存在的核心问题
- 内存可见性问题
普通全局变量的读写没有任何内存屏障保证,编译器优化、CPU缓存一致性机制都可能导致:主线程修改trigger_variable后,子线程长期读取到的是缓存/寄存器中的旧值,导致指令永远无法触发。 - 竞态条件问题
你写的两段逻辑都包含「读-判断-写」的非原子操作序列,极端时序下会出现逻辑异常:
比如子线程刚完成if(trigger_variable)判断为真、尚未执行trigger_variable=0的间隙,主线程刚好触发按钮逻辑,此时读取到的trigger_variable仍为1,就会跳过赋值操作,本次按钮触发事件直接丢失。 - 非原子读写风险
在部分非x86的异构架构下,普通变量的读写操作本身就不是原子的,如果变量地址未对齐,单次读写可能被拆分为多个总线操作,子线程可能读取到一半修改的脏值,触发不可预期的逻辑错误。
可行的替代方案
如果你不想引入互斥锁的开销,更适合这种轻量触发场景的方案是使用原子变量:
// 定义原子类型的触发变量(C11标准) #include <stdatomic.h> atomic_bool trigger_variable = ATOMIC_VAR_INIT(false); // 主线程逻辑 if (!atomic_load(&trigger_variable)) { atomic_store(&trigger_variable, true); } // 子线程逻辑 if (atomic_load(&trigger_variable)) { do_something(); atomic_store(&trigger_variable, false); }
如果确定要使用互斥锁,需要注意所有对trigger_variable的读、写操作都要在持有锁的区间内执行,不能只给写操作加锁。
内容的提问来源于stack exchange,提问作者Synthetix
相关产品推荐
相关产品推荐

