在cppreference.com上有关于std::memory_order
的文档,其中提供了一个放松序列的示例:
放松序列
被标记为
memory_order_relaxed
的原子操作不是同步操作;它们不会强制实施并发内存访问之间的顺序。它们只保证原子性和修改顺序的一致性。例如,假设x和y最初都为零,
// Thread 1: r1 = y.load(std::memory_order_relaxed); // A x.store(r1, std::memory_order_relaxed); // B // Thread 2: r2 = x.load(std::memory_order_relaxed); // C y.store(42, std::memory_order_relaxed); // D
它允许产生r1 == r2 == 42,因为尽管A在线程1内序列化于 B,C在线程2内序列化于 D,但是没有任何东西阻止D在y的修改顺序中出现在A之前,B在x的修改顺序中出现在C之前。D在y上的副作用可能会对线程1中的加载A可见,而B在x上的副作用可能会对线程2中的加载C可见。特别地,如果D在线程2中先于C完成,无论是由于编译器重新排序还是在运行时,都可能发生这种情况。
它说“C在线程2内的执行发生在D之前”。
根据评估顺序中的定义(可以在此处找到),如果A先于B序列化,则A的评估将在B开始之前完成。由于C在线程2内序列化于D,因此C必须在D开始之前完成,因此快照的最后一句话的条件部分永远不会被满足。