C++ C++;原子获取/释放操作它的实际含义

C++ C++;原子获取/释放操作它的实际含义,c++,atomic,C++,Atomic,我正在浏览这一页,试图理解内存模型同步模式。在以下示例中,从中提取: -Thread 1- -Thread 2- y = 1 if (x.load() == 2) x.store (2); assert (y == 1) 表示在线程1中存储到“y”的时间早于存储到x的时间。这里的“y”变量是普通全局变量还是原子变量 此外,如果线程2中“x”的加载得到了线程1中发生的存储的结果,那么它必须查看线程1中存储之前发生的所有操作,甚至是不相关的操作

我正在浏览这一页,试图理解内存模型同步模式。在以下示例中,从中提取:

 -Thread 1-       -Thread 2-
 y = 1            if (x.load() == 2)
 x.store (2);        assert (y == 1)
表示在线程1中存储到“y”的时间早于存储到x的时间。这里的“y”变量是普通全局变量还是原子变量

此外,如果线程2中“x”的加载得到了线程1中发生的存储的结果,那么它必须查看线程1中存储之前发生的所有操作,甚至是不相关的操作

那么,x.store()操作意味着所有对内存的读/写操作都应该更新各自的内存数据值,这意味着什么呢

然后对于std::memory\u order\u relaxed意味着“没有线程可以依赖于另一个线程的特定顺序””-这意味着什么-是不是编译器将进行重新排序,即使调用了y.store(),y meyno的值也不会被更新

-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 */
因为获取/释放记忆模型类似于顺序一致模式,只是它只对因变量应用“发生在之前”关系

Assuming 'x' and 'y' are initially 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)
它在明确的术语中是什么意思?

-thread1--thread2-
如果(x.load()==2),则y=1
x、 商店(2);断言(y==1)
  • 当然,编译器可能会更改不依赖于提高性能的操作顺序。
    但是当std::memory\u order\u seq\u cst起作用时,任何原子操作符都起作用。
    这并不意味着变量y是原子变量,编译器只保证
    y=1发生在
    x.store之前(2)。如果有另一个线程3操作变量y,则断言可能由于另一个线程而失败。
    如果我的解释很难理解(因为我的英语很差…),请检查&。
    如果A发生在建立B关系之前,那么如果B的副作用被发现,那么所有线程都必须看到A的副作用
  • -线程1-
    y、 存储(20,内存\u顺序\u松弛)//1-1
    x、 存储(10,内存\u顺序\u松弛)//1-2
    -线程2-
    如果(x.load(内存\u顺序\u松弛)==10)//2-1
    {
    断言(y.load(内存\u顺序\u松弛)==20)/*断言A*/
    y、 存储(10,内存\u顺序\u松弛)//2-2
    }
    -线程3-
    如果(y.load(内存\u顺序\u松弛)==10)//3-1
    断言(x.load(内存\u顺序\u松弛)==10)/*断言B*/
    
  • 要理解std::memory\u order\u released,您需要理解。显然,
    x
    y
    之间没有任何依赖关系。因此,编译器可能会更改线程1的执行顺序,这与std::memory_order_seq_cst不同,其中
    y.store(20)
    必须在
    x.store(10)
    发生之前执行。
    让我们看看每个断言如何失败。我已经为每个指令添加了标签。

    断言A:1-2→ 2-1 → 断言失败的
    断言B:有关详细答案,请参阅。

    简言之,线程3可能会看到最终更新的变量y并得到10,但不会产生
    1-2
    的副作用。即使线程2必须看到它的副作用才能将10存储到y中,编译器也不能保证指令的副作用必须在线程之间同步(发生在之前)

    另一方面,下面的示例是当指令具有数据依赖性时保留指令顺序的示例<代码>断言(请尝试阅读此有用的页面:。非常感谢您的详细解释-它帮助我理解了这个概念