c++ 几种内存约束

[参考] c++并发内存模型学习

[参考]c++内存模型和原子操作

memory_order_relaxed

最松散,或者说,不执行顺序一致性。该内存操作保证是原子操作,但可以在编译时优化或在运行时被cpu执行任意优化。而且在多核心平台上,relax操作产生的结果可能不会被立即同步到其他核心(没有synchronizes with属性),其他核心不会立即看见这个操作。relax的原子操作与上下文代码没有happens before的关系,也就是没有release语意。

memory_order_acquire和memory_order_release

这对操作具有acquire和release语义,被操作的内存变量在实施操作的核心之间有synchronizes with属性,可以保证源代码及编译后机器码顺序一致,但这种保证仍然不够严格,看这个例子:

 -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)

运行时,两个assert都可能同时不触发,在t3角度看来xy的改变顺序与t4角度允许不一致,xy顺序无关,无论在源代码的角度,还是机器码的角度。如果没有t3和t4的观察,xy的执行顺序既是x-y,也是y-x,是不是跟那个什么猫的实验很像。如果要所有核心看来顺序一致,就要用memory_order_seq_cst。

memory_order_consume

与acquire类似,但不会涉及到代码上下文内与原子操作不相关的内存变量,看这个例子:

-Thread 1-  

n = 1  

m = 1

p.store(&n, memory_order_release)

-Thread 2-  

t = p.load(memory_order_acquire);  

assert( *t == 1 && m == 1 );

-Thread 3-  

t = p.load(memory_order_consume);  

assert( *t == 1 && m == 1 );

t3会fail,因为p与m无关,(p只与n有关),所以t3角度只得到n,p的release结果,m没有被同步,相反,t2会同步n、m、及p。

memory_order_acq_rel:acquire + release

memory_order_seq_cst

最严格的顺序一致性,所有标记seq_cst的操作,顺序都不能被打乱(不能被编译器优化,不能被cpu乱序),无论从代码角度(源代码)还是cpu指令流(并发执行)的角度。在任意一个核心看来,所有标记为seq_cst的操作的顺序都一致

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值