内存屏障搭配volatile能否避免数据竞争?是否必须使用原子整数?
该实现是否线程安全?是否必须使用原子整数?
这种实现不是线程安全的,你必须使用原子整数来避免数据竞争问题。
核心问题分析
你的循环线程中,loop.loop_variable++是一个非原子的读-改-写操作,对应的汇编被拆成了三条独立指令:
movl loop.0(%rip), %eax // 读取loop_variable到寄存器 addl $1, %eax // 寄存器内完成加1 movl %eax, loop.0(%rip) // 将结果写回内存
这三条指令之间存在执行窗口,完全可能被另一个线程的写操作打断。
当另一个线程执行loops.loop_variable = loops.limit时(对应汇编是先读取limit到寄存器,再写回loop_variable),如果刚好在循环线程读取loop_variable到寄存器之后、写回之前完成写入,那么循环线程后续会把加1后的旧值写回内存,直接覆盖掉另一个线程设置的limit值。这会导致循环无法正确终止,或者出现其他不符合预期的执行结果,属于典型的数据竞争场景。
为什么需要原子整数
原子整数的增量操作(比如C++中的std::atomic<int>::fetch_add(1))会被编译成单条原子指令(x86平台上通常是lock addl),它能保证读-改-写的整个过程不会被其他线程打断,从根本上消除这类数据竞争。同时原子操作自带的内存序语义,也能配合你提到的内存屏障,保证线程间的内存可见性和操作顺序。
内容的提问来源于stack exchange,提问作者Samuel Squire
相关产品推荐
相关产品推荐

