标记为 std::memory_order_seq_cst 的单个原子操作会在所有地方触发顺序一致性吗?

Does a single atomic operation marked as std::memory_order_seq_cst trigger sequential consistency everywhere?

顺序一致性对所有线程施加了所有原子操作的全局顺序。据我所知,这意味着线程将按照源代码中指定的方式运行,不会重新排序。所有线程将按顺序执行它们的操作。

直觉上,它看起来像是要在多线程应用程序的 main() 函数中设置的选项或标志,类似于 "I want all my threads to follow sequential consistency"。当然在C++中没有这样的东西。

所以这是我的问题:代码中任何地方仅存在一条 x.load(std::memory_order_seq_cst)x.store(y, std::memory_order_seq_cst) 指令就足以强制所有线程,甚至是那些与 x 无关的线程以顺序一致的方式?

不,memory_order_seq_cst只保证所有memory_order_seq_cst原子accesses/fences的总序,见C++17标准终稿[atomics.order]/3。它不会将该要求强加于其他内存访问,即使是内存顺序较弱的原子访问。

例如,如果对于两个用 0 初始化的原子变量 std::atomic<int> x{0}, y{0};,线程 1 执行

x.store(1, std::memory_order_seq_cst);

并且线程 2 执行

y.store(1, std::memory_order_relaxed);

线程 3 和 4 执行时

auto a = x.load(std::memory_order_relaxed);
auto b = y.load(std::memory_order_relaxed);

然后线程 3 可以,例如观察 a == 1b == 0,而线程 4 观察 a == 0b == 1y 不通过任何 memory_order_seq_cst 操作访问,也不与 x 存储排序。因此,没有单一的线程间排序来确定 xy 上的存储发生的顺序。

在 C++17 标准最终草案的 [atomics.order]/8.

节中也有关于这一点的说明