1.double check (DCL)
- 这种为比较经典的写法,程序上看起来没有什么问题,且是线程安全的,但是在现在多核cpu 架构体系下,会进行指令重排,导致程序不会按预期的方式运行
#ifndef SINGLETON_TEMPLATE_H_
#define SINGLETON_TEMPLATE_H_
#include <mutex>
//thread-safe singleton template
template <class T>
class Singleton {
public:
static T* instance() {
if(instance_ == NULL) {
std::lock_guard<std::mutex> lock(mutex_create_instance_);
if(instance_ == NULL) { //check again for it may be changed by the other thread when the lock is released
instance_ = new T;
}
}
return instance_;
}
//release all the resources
static void destroy() {
if(instance_ != NULL) {
delete instance_;
instance_ = NULL;
}
return;
}
protected:
Singleton() {};
~Singleton() {};
/* class uncopyable */
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
private:
static T* instance_;
static std::mutex mutex_create_instance_; //make sure thread-safe singleton creation
};
2.linux 下的单例模式,相同的写法在c++ 11 中有 std::once_flag 库可以替代了,有相同的效果
template<typename T>
class Singleton
{
public:
static T& instance()
{
pthread_once(&ponce_,&Singleton::init);
return *value_;
}
private:
Singleton();
~Singleton();
static void init()
{
value_ = new T();
}
private:
static pthread_once_t ponce_;
static T* value_;
}
//必须在头文件中定义static 变量
template<typename T>
phread_once_t Singleton<T>::ponce_ = PTHREAD_ONCE_INIT;
template<truename T>
T* Singleton<T>::value_ = NULL;
3.使用static 包装,这种方式最简单,且是线程安全的,使用static 修饰,变量存储在静态存储区,在程序运行前就已经初始化好了
class CSingleton
{
CSingleton() {}
~CSingleton() {}
static CSingleton& getInstance()
{
static CSingleton m_instance;
return m_instance;
}
}
原文链接: https://www.cnblogs.com/bohat/p/13408445.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/200958
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!