6
// Thread 1
// do A
x.store(1, std::memory_order_release); // operation1

// Thread 2
// do B
x.store(2, std::memory_order_release); // operation2

// Thread 3
x.load(std::memory_order_acquire); // operation3

我了解到,如果thread3读取thread1写入的值,则release和acquire操作是同步的,并且thread3的效果A是可见的。
但如果是这样的话怎么办:

  • 修改顺序为x1, 2
  • thread3 读取 thread2 写入的值,因此 2发生在3 之前。

1 和 3 之间是否存在发生之前的关系?
或者本质上,修改顺序是否有助于发生之前的关系?

4

3 回答 3

4

不,操作 1 和操作 3 之间没有发生之前的关系。

来自[atomics.order]/2

对原子对象 M 执行释放操作的原子操作 A 与对 M 执行获取操作的原子操作 B 同步,并从以 A 为首的释放序列中的任何副作用获取其值。

...不幸的是,根据[intro.races]/5 ,操作 2 不在以操作 1 为首的发布序列中:

以原子对象 M 上的释放操作 A 为首的释放序列是 M 的修改顺序中副作用的最大连续子序列,其中第一个操作是 A,随后的每个操作都是原子读-修改-写操作

因此,我们无法在操作 1 和其他操作之间建立任何线程间发生之前的关系,因此操作 1 和操作 3 之间没有发生之前的关系。

于 2019-02-22T04:45:17.267 回答
1

在您的示例中,您显示线程 1 和线程 2 都以完全相同的方式在 x 上运行。因此,线程 1 和线程 3 的关系应该与线程 2 和线程 3 的关系完全相同。

您的示例没有显示任何会限制三个操作实际发生的顺序的代码行。换句话说,仅从这三个语句来看,无法判断加载操作是否会返回1、 或2或 的某个先前值x

于 2019-02-21T15:37:40.623 回答
1

如果我正确理解了您的问题,那么由于您使用的内存排序,因此对整体排序没有额外的保证。根本没有阻止允许这种情况发生。

于 2019-02-21T15:43:58.147 回答