多核环境下多线程操作原子变量是否需加锁及实现方案
多核场景下原子变量访问是否需要加锁的解答
结论先行
你给出的场景不需要额外加锁,原子操作的设计本身就覆盖了多核并发访问的场景。
原理说明
- 原子操作的底层是通过CPU提供的原子指令(比如X86的
LOCK前缀指令)实现的,不管是单核还是多核环境,CPU都会保证单个原子操作(atomic_load、atomic_store这类单次读写操作)的不可拆分性,多个核心同时对同一个原子变量发起原子操作时,CPU会自动协调总线/缓存一致性,保证不会出现读写撕裂、半写的问题。 - 你当前的代码里只有单次的原子存储和单次原子加载操作,没有「读-改-写」的复合操作逻辑,也没有依赖多个原子操作的连续执行顺序(如果有顺序要求只需要调整内存序即可,也不需要加锁),所以完全不需要额外加锁。
需要额外加锁的原子操作场景
只有出现以下情况时,才需要给原子变量的访问加锁:
- 需要执行多个原子操作的组合逻辑,要求整个组合逻辑整体原子执行
- 需要对原子变量执行非原子的复合操作,比如先读、计算、再写,且没有对应的「读-改-写」原子接口可用(
atomic_fetch_add这类本身就是原子的读改写操作也不需要加锁)
你提供的伪代码正确性说明
你贴的三个线程代码仅需要补全一处赋值逻辑就是完全安全的:
thread_1_function() { ... //End of use atomic_store(&v, 1); ... } thread_2_function() { ... atomic_store(&v, 2); ... } thread_3_function() { ... // 原代码漏了赋值给i的逻辑,补充后逻辑完全合法 int i = atomic_load(&v); if (i == 1) {...} else if (i == 2) {...} ... }
不管thread1和thread2运行在哪个核心上,
atomic_store写v的操作都是原子的,不会出现v一半是1一半是2的异常值;thread3的atomic_load读到的要么是1、要么是2、要么是v的初始值,一定是合法的完整值,不需要加锁就可以安全运行。
内容的提问来源于stack exchange,提问作者guoyanzhang
相关产品推荐
相关产品推荐

