创建单例的正确姿势

#define barrier() __asm__ volatile("lwsync")
volatile T* pInst = 0; //volatile关键字阻止编译器为了优化编译效率而调整了该变量的汇编指令顺序,简单来说就是禁止进行指令重排序。
T* getInstance()
{
  lock();
  if (!pInst) //锁内再加一个条件语句降低lock调用开销
  {
    T* temp = new T();
    barrier(); //阻止CPU因优化而动态调度调整指令顺序
    pInst = temp;
  }
  unlock();
  return pInst;
}

T* temp = new T();这一步骤其实由三小步构成:

(1)分配内存;
(2)在内存位置调用构造函数;
(3)将内存地址赋给指针。

在CPU动态调度优化时,可能发生改变以上三步顺序的情况,从1-2-3变成了1-3-2。如果1-3-2这种情况发生了,此时在(3)执行完后如果外部调用方紧接着使用pInst指针去调用该单例的某个实例方法,而该指针指向的内存区域中的构造函数尚未执行完,这个时间差就可能造成方法调用失败。

barrier()的插入就是可以保证temp在完全执行完毕后再执行下一步的赋值指令,无论前面是否存在CPU调整指令顺序的情况。

你可能感兴趣的:(创建单例的正确姿势)