【问题标题】:acquire/release memory ordering example获取/释放内存排序示例
【发布时间】:2013-11-15 15:59:56
【问题描述】:

我不明白来自here 的这个示例:

" 假设 'x' 和 'y' 初始为 0:

-Thread 1-
 y.store (20, memory_order_release);

 -Thread 2-
 x.store (10, memory_order_release);

 -Thread 3-
 assert (y.load (memory_order_acquire) == 20 && x.load (memory_order_acquire) == 0)

 -Thread 4-
 assert (y.load (memory_order_acquire) == 0 && x.load (memory_order_acquire) == 10)

这两个断言都可以通过,因为线程 1 和线程 2 中的存储之间没有强加排序。

如果此示例是使用顺序一致模型编写的,则其中一个存储必须在另一个之前发生(尽管直到运行时才确定顺序),值在线程之间同步,并且如果一个断言通过,另一个断言因此必须失败。 "

为什么acquire/release中的两个assert可以通过?

【问题讨论】:

  • @Oswald - 在这种情况下,伪代码就足够了。这就是通常描述和分析这种低级内容的方式。 SCCE 无济于事,因为运行它不会告诉您任何有用的信息:它可能会或可能不会显示排序差异,具体取决于系统和计时的详细信息。

标签: c++ multithreading concurrency atomic


【解决方案1】:

当您的内存模型不是顺序一致时,不同的线程可以看到世界的不同状态,并且以这样的方式,没有单一的全局状态(或状态序列)与两个线程一致见。

在示例中,线程 3 可以看到如下世界:

x = 0
y = 0
y = 20    // x still 0

线程 4 可以看到如下世界:

x = 0
y = 0
x = 10    // y still 0

世界的状态变化没有全局序列同时与这两种视图兼容,但如果内存模型不是顺序一致的,这正是允许的。

(事实上,该示例不包含任何演示发布/获取提供的肯定顺序保证的任何内容。因此,除了此处捕获的内容之外,还有很多其他内容,但它很好、简单地演示了放松的记忆顺序。)

【讨论】:

  • 我还是一头雾水。内存排序用于围绕一个标记的原子操作对非原子或其他原子操作进行排序。一个原子变量的原子加载怎么可能在另一个线程中看不到同一变量的原子存储?为什么 Th3 看到 y = 20 Th4 看不到 y = 20
  • @MohammadRB:因为每个线程都生活在自己的世界中。在 Th3 中,商店发生了,而在 Th4 中却没有。这就是没有一致性的意思。
  • 每当我认为我理解内存排序时,我都会看到一个让我害怕的例子。看来我是一个懒惰的学生,即使是像你这样的好老师也不能教我;)我不知道这是怎么回事。
  • @MohammadRB:您的大脑似乎天生就具有顺序一致性。试着忘记一切,想象每个线程都生活在一个完全独立的世界中,与任何其他世界无关。世界之间的唯一联系是同步点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-11
  • 2019-06-25
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
相关资源
最近更新 更多