C++單例模式的線程安全實踐與優化-CSDN博客
https://www.zhihu.com/question/56527586/answer/2344903391
C++11中的單例模式
在C++11及更高版本中,可以使用std::call_once和std::once_flag來確保單例實例的線程安全初始化。這種方法不需要顯式地使用互斥鎖,因為std::call_once會自動處理。
class Singleton {
private:
static std::unique_ptr<Singleton> instance;
static std::once_flag onceFlag;
Singleton() {}public:
static Singleton* getInstance() {
std::call_once(onceFlag, [] {
instance.reset(new Singleton());
});
return instance.get();
}
};std::unique_ptr<Singleton> Singleton::instance;
std::once_flag Singleton::onceFlag;
在實現單例模式時,需要考慮到線程安全、資源管理和程序的啟動時間。選擇合適的單例實現方法,可以根據具體的應用場景和需求來決定。在多線程環境中,確保線程安全是實現單例模式時的一個重要考慮因素。C++11提供的std::call_once是一個很好的工具,可以幫助簡化線程安全的單例實現。
餓漢式單例
餓漢式單例在程序啟動時就立即初始化。由于在程序啟動時就完成了初始化,因此它是線程安全的。但是,這種方法的缺點是不管你最終是否使用這個實例,它都會被創建,可能會導致資源的浪費。
class Singleton {
private:
static Singleton* instance;
Singleton() {}public:
static Singleton* getInstance() {
return instance;
}
};Singleton* Singleton::instance = new Singleton();
class Singleton {public :static volatile Singleton* GetInstance(int x = 0) {if (instance_ == NULL) {std::lock_guard<std::mutex> lock(mtx);if (instance_ == NULL) {volatile Singleton* temp = new volatile Singleton(x);instance_ = temp;}}return instance_;}void Print() { std::cout << this->member_ << std::endl;}private:Singleton(int x = 3) : member_(x) {}int member_;static volatile Singleton* instance_; //declare a static member variable
};volatile Singleton* Singleton::instance_ = NULL; //define a static member variable
懶漢式單例
懶漢式單例是指在第一次被引用時,才進行實例的初始化。這種方法的優點是延遲了實例的創建,因此在啟動時不會增加額外的負載。但是,這種方法在多線程環境下需要特別注意線程安全問題。
class Singleton {
private:
static Singleton* instance;
Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;public:
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};Singleton* Singleton::instance = nullptr;