C++11中的原子量和内存序详解

2020-01-06 19:27:01于海丽

 

step4使得c依赖于flag,当step4线程B读取到flag的值为true的时候,由于flag依赖于b,b在之前的写入是可见的,此时b一定为true,所以step6、step7的断言一定会成功。而且这种依赖关系具有传递性,假如b又依赖与另一个变量d,则d在之前的写入同样对step4之后的操作可见。那么a呢?很遗憾在这种内存序下a并不能得到保证,step5的断言可能会失败。

memory_order_acq_rel

这个选项看名字就很像release和acquire的结合体,实际上它的确兼具两者的特性。这个操作用于“读取-修改-写回”这一类既有读取又有修改的操作,例如CAS操作。可以将这个操作在内存序中的作用想象为将release操作和acquire操作捆在一起,因此任何读写操作的重拍都不能跨越这个调用。依然以一个例子来说明,flag为一个 atomic特化的bool 原子量,a、c各为一个int变量,b为一个bool变量,并且刚好按如下顺序执行:

 

step thread A thread B
1 a = 1  
2 flag.store(true, memory_order_release)  
3   b = true
4   c = 2
5   while (!flag.compare_exchange_weak(b, false, memory_order_acq_rel)) {b = true}
6   assert(a == 1)
7 if (true == flag.load(memory_order_acquire)  
8 assert(c == 2)