單例模式是一種非常常用的設計模式,幾乎在稍大的工程專案中都會用到。單例類保證在全域性中只有唯一乙個類的例項物件,並且在類的內部提供了獲取這個唯一例項的介面。在類中,例項化出乙個物件需要呼叫建構函式,為了防止在類的外部呼叫建構函式構造出例項,對類的建構函式就應有所限制,可以將建構函式的訪問許可權設定為private或protected。還要提供乙個訪問例項的介面,在類中定義乙個static函式,返回類內部唯一的例項物件即可。
class singleton
//防拷貝
singleton(const singleton&);
singleton& operator=(const singleton&);
public:
static singleton* getinstance() //宣告乙個靜態型別的介面來獲取例項
return _instance;
}private:
int _a;
//指向例項的指標定義為靜態私有,這樣定義靜態成員函式獲取物件例項
static singleton* _instance;
};singleton* singleton::_instance= null; //初始化靜態成員變數
建構函式能建立乙個例項物件,但是拷貝建構函式和賦值拷貝建構函式同樣可以,所以,可以用防拷貝的方法只宣告不定義,避免了多次建立例項物件。
上面的**,看起來貌似沒有什麼問題,但是若是在多執行緒下,有可能會建立多個singleton例項,所以為了防止這種情況,我們必須保證建立物件的過程時原子操作,則可以考慮加鎖。c++11的mutix標頭檔案中已經提供了lock和unlock,我們可以直接使用。
#include
class singleton
//防拷貝
singleton(const singleton&);
singleton& operator=(const singleton&);
public:
static singleton* getinstance() //宣告乙個靜態型別的介面來獲取例項
}return _instance;
}void delinstance() //銷毀例項
}private:
int _a;
static singleton* _instance;//宣告乙個靜態成員作為類的例項
static mutex _mtx;//保證執行緒安全的互斥鎖
};singleton* singleton::_instance = null; //初始化靜態成員變數
mutex singleton::_mtx;
以上**中加了互斥鎖,保證了執行緒安全。但也不是絕對安全的,因為加鎖或解鎖會引入新的問題,有可能拋異常或者造成死鎖。解決了執行緒安全,那麼就可以進一步提高效率。在上述**中,可以看到用了兩次判斷,也叫雙檢查機制,這就保證了只在第一次獲取物件時加鎖,避免高併發場景下每次獲取例項物件都進行加鎖,提高了效率。
懶漢模式:在第一次呼叫getinstance的時候才例項化出物件,此後返回的都是該物件。相對餓漢模式而言,複雜,要確保執行緒安全問題,但在各種場景下都適用。
餓漢模式:無論是否需要該類的例項,在程式一開始的時候會產生該類的例項物件,此後返回的都是該物件。由於是在main函式之前建立執行緒,可能會出現不確定問題,適用性受到限制。
上面**實現的是懶漢模式,那麼下邊就實現餓漢模式
namespace hungry
//防拷貝
singleton(const singleton&);
singleton& operator=(const singleton&);
public:
//static singleton& getinstance()
//static singleton& getinstance() //在類內部建立靜態例項,全域性只此乙份
void delinstance() //銷毀例項
}private:
int _a;
static singleton* _instance;
};singleton* singleton::_instance = null;
//singleton* singleton::_instance = new singleton();//全域性生成乙個例項物件
}
指令流水作業時,系統可能會為了提高效率,將執行流的順序打亂,這時候進行外部的檢查時,可能內部的**還沒有完全執行完,但是已經滿足了外部的判斷條件,那麼執行就會出錯。
比如,建立乙個例項物件,正確的執行流是:
1.operator new建立空間
2.呼叫建構函式初始化成員變數
3.賦值
打亂之後的:
1.operator new建立空間
2.賦值
3.呼叫建構函式初始化成員變數
這時候為了避免這種情況,可以使用記憶體屏障memorybarrier,保證其之前和之後的順序流不被打亂。
static singleton* getinstance()
}return _instance;
}
參考: C 執行緒安全的單例類
單例模式是一種非常常用的設計模式,幾乎在稍大的工程專案中都會用到。單例類保證在全域性中只有唯一乙個類的例項物件,並且在類的內部提供了獲取這個唯一例項的介面。在類中,例項化出乙個物件需要呼叫建構函式,為了防止在類的外部呼叫建構函式構造出例項,對類的建構函式就應有所限制,可以將建構函式的訪問許可權設定為...
C 實現執行緒安全的單例模式
廢話不多說,常用的 積澱下來。一 懶漢模式 即第一次呼叫該類例項的時候才產生乙個新的該類例項,並在以後僅返回此例項。需要用鎖,來保證其執行緒安全性 原因 多個執行緒可能進入判斷是否已經存在例項的if語句,從而non thread safety.使用double check來保證thread safe...
實現單例模式的執行緒安全的類
單例模式 是設計模式中比較簡單的一種,適合於乙個類只有乙個例項的情況,比如視窗管理,列印緩衝池和檔案系統 單例模式特點 一.確保乙個類只有乙個例項被建立 2.在不影響單例類的客戶端的情況下允許將來有多個例項,經典的模式 懶漢式,餓漢式,登記式 3.提供了乙個對全域性物件的全域性訪問指標 模式 一.懶...