多线程环境过度优化下的CPU乱序问题

volatile关键字对过度优化的使用

volatile的作用: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.(优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份)

举例

x=0;
//Thread1     Thread2
lock();     lock();
x++;        x++;
unlock();   unlock();

Thread1先进入加锁区域,Thread2被lock()阻塞前,如果先将x=0放入了寄存器中,那么加锁也就没有意义了。

使用volatile关键字可解决上述问题

Singleton模式下CPU乱序问题

先看如下代码

Volatile T* pInst = 0;
T* GetInstance()
  {
    if(!pInst)
      {
        lock();
        if(!pInst)
          pInst = new T;
        unlock();
      }
    return pInst;
  }

这样的代码在CPU乱序下的问题如下:

pInst = new T;实际上包含了3个步骤:

(1)分配内存;

(2)调用构造函数;

(3)将内存地址返回并赋值给pInst

然而(2)(3)步骤是可以颠倒的。即CPU在构造函数被调用完成之前就已经返回了地址;当其他线程此时使用该指针则会出现错误。

解决此问题的方法为barrier指令

Volatile T* pInst = 0;
T* GetInstance()
  {
    if(!pInst)
      {
        lock();
        if(!pInst)
        {
          T *temp= new T;
          barrier();//
          pInst = temp;
         }
        unlock();
      }
    return pInst;
  }

关于barrier指令

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值