這不是一個娛樂文章,這是一個C/C++知識學習之地。今天學習的是痴漢模式,不好意思是單例模式。
單例模式
一個類只允許有一個實例,這就是著名的單例模式。單例模式分為懶漢模式,跟餓漢模式兩種。
餓漢模式的實現
餓漢模式:在程序啟動或單件模式類被加載的時候,單件模式實例就已經被創建。
- 構造函數私有化或者保護化
- .禁止拷貝和賦值
- 靜態的共有接口
- 初始化靜態數據成員
在實例化m_instance 變量時,直接調用類的構造函數。顧名思義,在還未使用變量時,已經對m_instance進行賦值,就像很飢餓的感覺。這種模式,在多線程環境下肯定是線程安全的,因為不存在多線程實例化的問題。
懶漢模式的實現
懶漢模式:當程序第一次訪問單件模式實例時才進行創建。
懶漢模式下,在定義m_instance變量時先等於NULL,在調用GetInstance()方法時,在判斷是否要賦值。這種模式,並非是線程安全的,因為多個線程同時調用GetInstance()方法,就可能導致有產生多個實例。要實現線程安全,就必須加鎖。
多線程安全的單例模式
1.普通加鎖方式
這一切看起來都很完美,但是程序猿是一種天生就不知道滿足的動物。他們發現GetInstance()方法,每次進來都要加鎖,會影響效率。然而這並不是必須的,於是又對GetInstance()方法進行改進。
2.雙鎖機制
這也就是所謂的“雙檢鎖”機制。但是有人質疑這種實現還是有問題,在執行 m_instance = new T()時,可能 類T還沒有初始化完成,m_instance 就已經有值了。這樣會導致另外一個調用GetInstance()方法的線程,獲取到還未初始化完成的m_instance 指針,如果去使用它,會有意料不到的後果。其實,解決方法也很簡單,用一個局部變量過渡下即可
3.完整版本
到這裡在懶漢模式下,也就可以保證線程安全了。然而,在linux下面還有另一種實現。linux提供了一個叫pthread_once()的函數,它保證在一個進程中,某個函數只被執行一次。不過這些就留給有興趣,有需求的讀者自己實現了。好了,有需求,可以私信我“代碼”獲取更多C/C++學習內容。
更多精彩
閱讀更多 C語言源代碼計劃 的文章