使用 memory_order_relaxed 复制竞争条件

问题描述 投票:0回答:1
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
c++ memory-barriers
1个回答
1
投票

从规范的角度来看,断言失败和断言成功都是程序允许的行为。

但这并不意味着您可以期望以某种概率看到这两种行为。相反,您根本无法保证您会观察到哪种行为。

实际上来说,这主要取决于编译器在将

write
中的两个存储转换为目标架构中的存储时是否对它们重新排序。在某些架构上,CPU 的重新排序也可能相关,但并非如此。在 x86 上。

© www.soinside.com 2019 - 2024. All rights reserved.