#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調整指令順序的情況。