#include <pthread.h> // 提供pthread_once函数
#include <boost/noncopyable.hpp> // 禁止拷贝构造和赋值操作
template<typename T>
class Singleton : boost::noncopyable // 继承禁止拷贝的基类
{
public:
static T& instance() {
// 关键:pthread_once保证init函数仅执行一次(线程安全)
pthread_once(&ponce_, &Singleton::init);
return *value_;
}
private:
Singleton(); // 构造函数私有化
~Singleton(); // 析构函数私有化
static void init() { // 实际初始化函数
value_ = new T(); // 创建单例对象
}
private:
// C++17, 允许静态成员变量使用inline直接定义+初始化
inline static pthread_once_t ponce_ = PTHREAD_ONCE_INIT; // once控制变量(线程安全初始化)
inline static T* value_ = NULL; // 单例对象指针
};
// Use example:
Foo& foo = Singleton<Foo>::instance();
该单例模式的线程安全由Pthreads库保证,使用pthread_once_t这个控制变量来保证lazy_initialization的线程安全。
使用静态的pthread_once_t类型控制变量,并初始化为PTHREAD_ONCE_INIT,该控制变量状态分为NEVER(未初始化)、IN_PROGRESS(初始化中)、DONE(已完成)。首次调用时,状态从NEVER转为IN_PROGRESS,初始化完成后标记为DONE。
若多个线程同时调用pthread_once,只有第一个线程进入初始化流程,其他线程阻塞等待;初始化完成后,所有线程直接获取结果,保证了线程安全地初始化。避免了传统懒汉式单例需手动加锁(如pthread_mutex_lock)引入的性能开销。