void experiment_relaxed() {
atomic<int> x;
atomic<int> y;
auto write = [&x, &y]() {
y.store(10, memory_order_relaxed);
x.store(1, memory_order_relaxed);
};
auto read = [&x, &y]() {
if (x.load(memory_order_relaxed) == 1) {
assert(y.load(memory_order_relaxed) == 10);
}
};
auto reader = thread{read};
auto writer = thread{write};
reader.join();
writer.join();
}
我期望由于
x
和 y
都是原子变量并且使用 memory_order_relaxed
,因此写入顺序应该是任意的。但即使运行此函数 100,000 多次,assert
也不会失败。什么可能会强制订购?
这个实验在某种程度上基于https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
编译它
g++ -O3 -std=c++20 test.cpp -o test
从规范的角度来看,断言失败和断言成功都是程序允许的行为。
但这并不意味着您可以期望以某种概率看到这两种行为。相反,您根本无法保证您会观察到哪种行为。
实际上来说,这主要取决于编译器在将
write
中的两个存储转换为目标架构中的存储时是否对它们重新排序。在某些架构上,CPU 的重新排序也可能相关,但并非如此。在 x86 上。