实现线程安全的单例,如果使用简单的加锁同步机制,则要同时使用单例引用的缓存,才能勉强达到工业级强度。为了提高性能,而提出的双重检测加锁(DLCP)方式实现的单例据Scott Meyers大牛指出是不可靠的。参见https://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
除了以上通过加锁实现线程安全的单例模式以外,还有两种比较好的方式,代码也比较简洁。
1、利用C++11新特性,即local static变量的初始化是线程安全的,来实现单例。
template<typename T> struct Singleton { static T& getInstance() { static T pInstance; return pInstance; } private: Singleton() = delete; ~Singleton() = delete; };
2、使用pthread_once函数。无论在单线程还是多线程程序中,该函数可以确保,被传入的函数只会被执行一次。
template<typename T> struct Singleton : UnCopyable { static T& getInstance() { pthread_once(&pOnce, &Singleton::init); return *pInstance; } private: static void init() { pInstance = new T(); } Singleton() = delete; ~Singleton() = delete; private: static T* pInstance; static pthread_once_t pOnce; };