C++雙鎖機制實現單例模式多線程安全的單例模式

這不是一個娛樂文章,這是一個C/C++知識學習之地。今天學習的是痴漢模式,不好意思是單例模式。

C++雙鎖機制實現單例模式多線程安全的單例模式

完整代碼,以及更多學習資料,私信“代碼“獲取

單例模式

一個類只允許有一個實例,這就是著名的單例模式。單例模式分為懶漢模式,跟餓漢模式兩種。

餓漢模式的實現

餓漢模式:在程序啟動或單件模式類被加載的時候,單件模式實例就已經被創建。

C++雙鎖機制實現單例模式多線程安全的單例模式

更多C/C++學習資料,請私信我“代碼”,即可獲取

  • 構造函數私有化或者保護化
  • .禁止拷貝和賦值
  • 靜態的共有接口
  • 初始化靜態數據成員

在實例化m_instance 變量時,直接調用類的構造函數。顧名思義,在還未使用變量時,已經對m_instance進行賦值,就像很飢餓的感覺。這種模式,在多線程環境下肯定是線程安全的,因為不存在多線程實例化的問題。

C++雙鎖機制實現單例模式多線程安全的單例模式

更多C/C++學習資料,請私信我“代碼”,即可獲取

懶漢模式的實現

懶漢模式:當程序第一次訪問單件模式實例時才進行創建。

C++雙鎖機制實現單例模式多線程安全的單例模式

更多C/C++學習資料,請私信我“代碼”,即可獲取

懶漢模式下,在定義m_instance變量時先等於NULL,在調用GetInstance()方法時,在判斷是否要賦值。這種模式,並非是線程安全的,因為多個線程同時調用GetInstance()方法,就可能導致有產生多個實例。要實現線程安全,就必須加鎖。

多線程安全的單例模式

1.普通加鎖方式

C++雙鎖機制實現單例模式多線程安全的單例模式

更多C/C++學習資料,請私信我“代碼”,即可獲取

這一切看起來都很完美,但是程序猿是一種天生就不知道滿足的動物。他們發現GetInstance()方法,每次進來都要加鎖,會影響效率。然而這並不是必須的,於是又對GetInstance()方法進行改進。

2.雙鎖機制

C++雙鎖機制實現單例模式多線程安全的單例模式

更多C/C++學習資料,請私信我“代碼”,即可獲取

這也就是所謂的“雙檢鎖”機制。但是有人質疑這種實現還是有問題,在執行 m_instance = new T()時,可能 類T還沒有初始化完成,m_instance 就已經有值了。這樣會導致另外一個調用GetInstance()方法的線程,獲取到還未初始化完成的m_instance 指針,如果去使用它,會有意料不到的後果。其實,解決方法也很簡單,用一個局部變量過渡下即可

3.完整版本

C++雙鎖機制實現單例模式多線程安全的單例模式

更多C/C++學習資料,請私信我“代碼”,即可獲取

到這裡在懶漢模式下,也就可以保證線程安全了。然而,在linux下面還有另一種實現。linux提供了一個叫pthread_once()的函數,它保證在一個進程中,某個函數只被執行一次。不過這些就留給有興趣,有需求的讀者自己實現了。好了,有需求,可以私信我“代碼”獲取更多C/C++學習內容。

C++雙鎖機制實現單例模式多線程安全的單例模式

完整代碼,以及更多學習資料,私信“代碼“獲取

更多精彩


分享到:


相關文章: