【发布时间】:2021-01-26 09:53:37
【问题描述】:
我正在阅读来自 GCC Wiki 的 this article 关于 C++ 内存屏障(及其真棒)。
在我到达这一点之前,这非常简单:
相反的方法是 std::memory_order_relaxed。该模型通过删除发生前的限制来减少同步。这些类型的原子操作还可以对其执行各种优化,例如死存储删除和共享。 所以在前面的例子中:
-Thread 1-
y.store (20, memory_order_relaxed)
x.store (10, memory_order_relaxed)
-Thread 2-
if (x.load (memory_order_relaxed) == 10)
{
assert (y.load(memory_order_relaxed) == 20) /* assert A */
y.store (10, memory_order_relaxed)
}
-Thread 3-
if (y.load (memory_order_relaxed) == 10)
assert (x.load(memory_order_relaxed) == 10) /* assert B */
由于线程不需要跨系统同步,因此本例中的任何一个断言实际上都可能失败。
好的,这也很简单,让我们继续..
-Thread 1-
x.store (1, memory_order_relaxed)
x.store (2, memory_order_relaxed)
-Thread 2-
y = x.load (memory_order_relaxed)
z = x.load (memory_order_relaxed)
assert (y <= z)
断言不能失败。一旦线程 2 看到 2 的存储,它就不能再看到值 1。这可以防止将一个变量的松弛负载合并到可能别名的不同引用的松弛负载。
这让我很困惑,为什么 y 不能加载值 2 而 z 加载值 1(并导致断言失败),因为线程 1 中的排序不同步?
【问题讨论】:
-
链接中缺少的段落说:“唯一的排序是,一旦在线程 2 中观察到来自线程 1 的变量的值,线程 2 就看不到“更早”该变量的值来自线程 1".
标签: c++ multithreading synchronization atomic