c++ memory order

本文探讨了在多线程编程中如何使用C++11的原子操作和内存屏障来避免代码优化导致的问题。通过std::atomic变量和memory_order属性,确保线程间的同步正确性,防止编译器和CPU指令重排序。示例展示了如何使用memory_order_release和memory_order_acquire来保证数据一致性。
摘要由CSDN通过智能技术生成

很多时候写多线程应用程序,习惯弄一个原子变量来做线程间的同步。

比如代码

std::atomic<bool> ready = false;

p.Init();

ready = true;

 

if (ready) {

    p.bar();

}

线程2在等待ready被设置,

代码可能会被优化成ready在Init之前被设置,这样就会出现问题了。

那么怎样避免代码被优化呢?

为了解决这个问题,cpu和编译器提供了memory fence,让用户可以声明访存指令的可见性关系,c++11总结为以下memory order:

memory order作用
memory_order_relaxed无fencing作用,cpu和编译器可以重排指令
memory_order_consume后面依赖此原子变量的访存指令勿重排至此条指令之前
memory_order_acquire后面访存指令勿重排至此条指令之前
memory_order_release前面的访存指令勿排到此条指令之后。当此条指令的结果被同步到其他核的cache中时,保证前面的指令也已经被同步。
memory_order_acq_relacquare + release
memory_order_seq_cst

acq_rel + 所有使用seq_cst的指令有严格的全序关系

代码改成

 

// Thread1 // ready was initialized to false

p.init();

ready.store(true, std::memory_order_release);

 

// Thread2

if (ready.load(std::memory_order_acquire))

{ p.bar(); }

补充下:c++11的原子操作是加了内存屏障的,所以放心大胆用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值