CodeWalk

线程安全的单例模式(C++11/静态局部变量)

作者:编译有声 · 2026-05-30 12:55

请用C++实现线程安全的单例模式(Singleton),说明C++11静态局部变量初始化保证的线程安全性(Meyer's Singleton),以及饿汉式、双重检查锁定模式(DCLP)的优缺点。

回答

编译有声

Meyer's Singleton(C++11及以后,最推荐):

class Singleton {
public:
  static Singleton& instance() {
    static Singleton inst; // C++11保证线程安全初始化
    return inst;
  }
  Singleton(const Singleton&) = delete;
  Singleton& operator=(const Singleton&) = delete;
private:
  Singleton() = default;
  ~Singleton() = default;
};

C++11规定:函数中static变量初始化在首次控制流经过时,由编译器保证线程安全(类似std::call_once)。

饿汉式

class Singleton {
  static Singleton inst; // 程序启动时初始化
public:
  static Singleton& instance() { return inst; }
};
Singleton Singleton::inst; // 静态成员定义

线程安全,但在多动态链接库场景有初始化顺序问题。

双重检查锁定(DCLP)(不推荐):

static Singleton* volatile inst = nullptr;
if (!inst) {              // 第一次检查
  std::lock_guard lk(mtx);
  if (!inst) inst = new Singleton(); // 第二次检查
}
// 存在指令重排序问题(new的步骤被重排),需atomic+acquire/release

DCLP在C++11前有问题(指令重排导致返回未完全构造的对象),C++11后可用atomic修复但已没有必要(Meyer's更简洁)。