无锁场景下两个进程访问共享内存的intVar、pidVar取值疑问
问题解答
1. 两个进程均完成累加后,intVar的最终值是否每次运行都保持一致?
结论是不能保证一致。
普通int的累加操作本身不是原子指令,在CPU层面会被拆分为三步:从共享内存读取当前值到寄存器、寄存器执行加法计算、将计算结果写回共享内存。全程无锁的情况下,这三步中间随时可能被操作系统打断切换到另一个进程,或者两个进程在不同CPU核心上并行执行,非常容易出现竞态:
- 举个实际场景:假设进程A要加1,进程B要加2,初始值是5。如果进程A刚读完值为5,还没来得及写回计算结果6,进程B也读到了值为5,计算得到7后写回,之后进程A再把自己的6写回,最终结果就是7,而不是预期的5+1+2=8。
这种情况会不会出现完全看操作系统的调度时机,所以每次运行的结果没有确定性。
2. 共享内存中pidVar的最终取值是否完全随机?
结论是不是真正的随机,但上层应用无法预判结果。
首先,对齐的pid_t类型的单次读、写操作在绝大多数主流架构上都是原子的,不会出现一半是进程A的pid、一半是进程B的pid的脏数据,最终的结果只会是两个进程其中之一的pid,不可能还保持初始的0。
最终哪个进程的pid会留下来分两种情况:
- 第一个写入pid的进程执行完写入操作后,第二个进程才读取
pidVar,此时第二个进程发现值不是0就不会写入,结果就是第一个进程的pid。 - 两个进程都先读到了
pidVar为0的状态,之后先后执行写入操作,最终结果是后完成写入的那个进程的pid。
不管是哪种情况,结果都取决于操作系统的进程调度时序、CPU核心的执行顺序等底层因素,不是真随机事件,但上层程序没有办法稳定预测每次运行的结果。
内容的提问来源于stack exchange,提问作者Agrudge Amicus
相关产品推荐
相关产品推荐

