//執行緒非安全版本
singleton* singleton::getinstance()
return m_instance;
}
如果兩個執行緒都進入該函式,則此時判斷m_instance的值都為nullptr,因此兩個執行緒都進入條件語句中new出來乙個單例模式的例項。
讀操作是不需要加鎖的,但是這種方式會因為對讀操作加鎖來產生浪費
singleton* singleton::getinstance()
return m_instance;
}
先來說一下雙鎖的妙處第乙個鎖可以避免讀操作時的加鎖行為帶來的損耗,因為——讀操作時,m_instance不為空。
第二個鎖用於防止多產生例項化物件。因為——在加鎖之前,兩個執行緒因為都判斷m_instance為空而進入到條件語句中。即便有乙個執行緒先加鎖了,生成了乙個例項化物件,那麼另乙個執行緒也進來了,等第乙個執行緒釋放鎖之後,就會去執行建立,從而多建立出乙個物件。
因此需要雙鎖來確保只建立乙個物件。
singleton* singleton::getinstance()
}return m_instance;
}
但是雙鎖法不能用,因為記憶體讀寫reorder會導致雙鎖失效。原因如下:
什麼是reorder——**都有指令序列,我們都認為**會按照指令序列去執行。但是到了彙編層,也就是到了指令層次(我們知道,執行緒會在指令層搶時間片)
對於上側**中的建立例項動作,會分為三步
m_instance = new singleton();
reorder之後很可能會變成先分配記憶體、再把指標給m_instance,然後在執行構造器會出現的問題:reorder之後,先分配記憶體,然後把記憶體分配給m_instance,此時m_instance就不是null了。乙個執行緒進來發現m_instance不是null,就直接執行
return m_instance;
獲取了物件例項,但是此時還沒執行構造器,所以執行緒此時獲取的是一塊沒被賦值的原生記憶體,這會導致錯誤發生
因此這個不能用,出錯概率很高
//c++ 11版本之後的跨平台實現 (volatile)
//volatile宣告是告訴編譯器,不能對下面的執行過程進行reorder的
//通過atomic宣告乙個原子物件
設計模式(物件效能) 單件模式
單件模式 確保乙個類只有乙個例項,並提供乙個全域性訪問點。場景還原 巧克力工廠 現代化的巧克力工廠具備計算機控制的巧克力鍋爐,鍋爐做的事,就是把巧克力和牛奶融在一起,然後送到下乙個階段,以製造成巧克力棒。鍋爐控制器常用於防止不好的事情發生,例如,排出500加侖未煮沸的混合物,或者鍋爐已經滿了還繼續放...
設計模式 單例模式
單例模式 singleton pattern 是乙個比較簡單的模式,其定義如下 ensure a class has only one instance,and provide a golbal point of acess to it.確保某乙個類只有乙個例項,而且自行例項化並且向整個系統提供這個...
設計模式 單例模式
class testsingleton static public function instance return self testsingleton private function clone public function setsinvar sinvar public function ...