GCC Wiki说明了内存模型同步模式Acquire/Release:
为了使事情变得更复杂,非原子变量的相互作用仍然是相同的。必须在同步的其他线程中看到原子操作之前的任何存储。例如:
-Thread 1- y = 20; x.store (10, memory_order_release); -Thread 2- if (x.load(memory_order_acquire) == 10) assert (y == 20);因为' y'不是一个原子变量,商店到' y' 在商店之前发生 - ' x'因此断言在这种情况下不会失败。优化器仍必须限制在原子操作周围对共享内存变量执行的操作。
现在,如果我做了' y'一个原子变量(没有强加发生在之前的限制)?
-Thread 1-
y.store (20, memory_order_relaxed);
x.store (10, memory_order_release);
-Thread 2-
if (x.load(memory_order_acquire) == 10)
assert (y.load (memory_order_relaxed) == 20);
断言失败了吗?原子变量的要求是否少于非原子变量?或者,维基对非原子变量的限制在这里是无端和误导的吗?
答案 0 :(得分:3)
因为' y'不是一个原子变量,商店到' y'发生在商店之前的' x'
声明"因为y
不是原子"是不正确的..
相同的排序规则适用于原子和非原子操作。
获取/释放障碍保证存储操作A(存储到y
)在存储/释放发生之前排序< - > 内存操作B(assert
)
在看到存储值的加载/获取之后排序。操作A和B是否是原子的是无关紧要的
assert
无法触发。