C++单例模式与线程安全
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;