在该场景下是否可省略release与acquire内存屏障?
关于x86/64架构下省略内存屏障的问题解答
先直接给结论:完全可以省略这两个内存屏障,原因和x86/64架构的内存模型特性直接相关。
我们先明确一个关键特性:
x86/64架构上的每一次
load操作都隐含acquire语义,每一次store操作都隐含release语义。
接下来对应你的代码逐一分析:
线程A的flag = 1:可以省略release屏障
线程A中,flag = 1是一次store操作,而x86/64的store天生带有release语义。这意味着:
- 所有在这个store之前的写操作(也就是
number1 = 12345和number2 = 678910)绝对不会被CPU重排到flag = 1之后执行; - 当其他线程看到
flag被设置为1时,一定能看到这两个number变量的更新值。
所以完全不需要额外添加release屏障。
线程B的while (flag == 0) {}:可以省略acquire屏障
线程B中,循环里对flag的读取是一次load操作,x86/64的load天生带有acquire语义。这意味着:
- 所有在这个load之后的读操作(也就是读取
number1和number2)绝对不会被CPU重排到flag的load之前; - 一旦
flag的load返回1,后续读取number变量时,能保证看到线程A在flag = 1之前完成的所有写操作。
所以也完全不需要额外添加acquire屏障。
总结来说,在x86/64架构下,你的代码依靠硬件本身提供的内存语义就可以保证线程B能正确看到线程A的变量更新,不需要手动添加额外的内存屏障。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

