c 單例模式與執行緒安全(二)

2021-10-01 06:55:38 字數 1992 閱讀 9980

試想一下,如果有多執行緒的情況下,兩種單例模式是否安全?是否會出現建立多個例項的情況呢?下面先來看一下餓漢方式的單例模式,在此之前,我再把餓漢方式的實現**拷貝過來,有助於分析。

#include

using

namespace std;

class

config

private

:static config* temp;

public:~

config()

void

readconfig()

void

writeconfig()

public

:static config*

getinstance()

};config* config::temp =

newconfig()

;//建立例項

intmain()

很明顯,餓漢是執行緒安全的。因為餓漢模式下例項很早就建立了,假設在main中建立了兩個執行緒去獲取例項,兩個執行緒返回的例項都會是最早建立的那個例項,因此不存在會建立多個例項的情況。

再來看一下懶漢方式下的執行緒安全,同樣的,先拷貝乙份懶漢模式的**以便分析。

#include

using

namespace std;

class

config

private

:static config* temp;

public:~

config()

void

readconfig()

void

writeconfig()

public

:static config*

getinstance()

};config* config::temp =

null

;int

main()

我們假設有兩個執行緒需要獲取config的例項。當執行緒1呼叫getinstance(),並且判斷temp == null為真,因為此時還沒有例項,此時切到執行緒2也同樣呼叫了getinstance(),並且也判斷了temp== null為真,然後執行緒2建立了乙個例項,再切回到了執行緒1 ,這樣執行緒1也建立了例項,可以看出在兩個執行緒下,懶漢有肯能會建立兩個例項。

如何避免這種情況呢?也很簡單,加鎖就可以了,鎖是常用的使執行緒同步的一種方式。

#include

#include

using

namespace std;

class

config

public:~

config()

void

readconfig()

void

writeconfig()

public

:static config*

getinstance()

};config* config::temp =

null

;pthread_mutex_t config::mutex;

intmain()

互斥鎖是比較常用的一種鎖,在訪問全域性變數時之前加鎖,訪問完之後解鎖,這樣可以保證多執行緒中的全域性變數是同步的。採用上述加鎖的**之後,我們再來分析一下兩個執行緒的情況。

首先執行緒1呼叫getinstance()函式並且對mutex加鎖,判斷temp == null為真,進入條件語句中,此時切到執行緒2,也呼叫getinstance()函式,由於mutex已經被執行緒1鎖定,執行緒2不持有mutex,所以執行緒2會阻塞pthread_mutex_lock這個函式中,然後又切回到執行緒1,執行緒1建立了乙個單例的例項,並且解鎖,再切回到執行緒2,執行緒2給mutex加鎖,再判斷temp == null,這個條件為假,因為temp的值已經被執行緒1給賦值了,所以直接返回了temp,即執行緒1建立的例項,再解鎖。這樣就滿足了在多執行緒的情況下也不會建立多個例項,滿足單例模式的設計思想。

C 單例模式 與執行緒安全

單例模式 作為物件的建立模式,單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。在下面 的物件圖中,有乙個 單例物件 而 客戶甲 客戶乙 和 客...

C 單例模式與執行緒安全

1.教科書裡的單例模式 我們都很清楚乙個簡單的單例模式該怎樣去實現 建構函式宣告為private或protect防止被外部函式例項化,內部儲存乙個private static的類指標儲存唯一的例項,例項的動作由乙個public的類方法代勞,該方法也返回單例類唯一的例項。上 class singlet...

c 多執行緒單例模式 執行緒安全C 單例模式

我對此處記錄的單例模式有一些疑問 http us library ff650316.aspx 以下 摘自該文章 using system public sealed class singleton private static volatile singleton instance private ...