c++中的 单例模式(singleton)和双检测锁(Double-Checked Locking)
懶漢式實現(xiàn)的單例模式
上文中給出的懶漢式實現(xiàn)的單例模式,在單線程中使用時完全沒有問題的,但是在多線程中使用會存在多次對象多次創(chuàng)建的問題。
為了解決這個問題需要使用雙檢測,詳情可參考
C++ and the Perils of Double-Checked Locking
里面詳細說明了雙重檢測的方法,和最終的解決方案。
要想解決上述懶漢單例模式中的問題,需要引入這個雙重檢測的功能,實現(xiàn)也只需將圖中的代碼在加鎖的基礎上,在添加一層檢測
臨界區(qū)(Critical Section)。臨界區(qū)對象通過提供一個進程內所有線程必須
共享的對象來控制線程。只有擁有那個對象的線程可以訪問保護資源。在另一個線
程可以訪問該資源之前,前一個線程必須釋放臨界區(qū)對象,以便新的線程可以索取對象的訪問權
最終實現(xiàn)效果如下
if (m_psl == NULL) {// 這里線程開始資源競爭,只有一個線程能獲取lock的資源lock();if (m_psl == NULL){m_psl = new Singelton;}unlock(); }說明:
lock里面判斷一次,因為可能有多個線程在lock處等待,一個成功之后,會將m_psl設置為非空,這樣下個線程就算拿到lock資源,再進去發(fā)現(xiàn)指針非空就離開了
lock外判斷一次,是因為獲取鎖,是很浪費時間的,獲取鎖之外還有一層判斷,那么在第二次獲取單例對象的時候,lock外的if判斷發(fā)現(xiàn)指針已經非空,就不會再獲取鎖了,直接返回了對應的對象,這樣雙層檢測,即保證了對象創(chuàng)建的唯一性,又減少了獲取鎖浪費的時間和資源
不安全的單例模式代碼:
#include <iostream> using namespace std;//懶漢式 class Singelton { private:Singelton(){cout << "Singelton 構造函數(shù)執(zhí)行" << endl;} public:static Singelton *getInstance(){if (m_psl == NULL){m_psl = new Singelton;}return m_psl;}static void FreeInstance(){if (m_psl != NULL){delete m_psl;m_psl = NULL; }}private:static Singelton *m_psl; };Singelton *Singelton::m_psl = NULL;void main041() {Singelton *p1 = Singelton::getInstance();Singelton *p2 = Singelton::getInstance();if (p1 == p2){cout << "是同一個對象" << endl;}else{cout << "不是同一個對象" << endl;}Singelton::FreeInstance();return ; }總結
以上是生活随笔為你收集整理的c++中的 单例模式(singleton)和双检测锁(Double-Checked Locking)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【2015年第4期】大数据时代的数据挖掘
- 下一篇: 【软件测试】软件测试札记