CodeWalk

C++单例模式线程安全的最佳实践

作者:我还是少年 · 2026-05-30 12:55

请给出C++中双检锁(DCLP)单例的线程安全实现,并说明为什么需要std::atomic。

回答

我还是少年

双检锁需要std::atomic和内存序防止指令重排:

class Singleton {
    static std::atomic<Singleton*> instance;
    static std::mutex mtx;
public:
    static Singleton& getInstance() {
        Singleton* p = instance.load(std::memory_order_acquire);
        if (!p) {
            std::lock_guard lock(mtx);
            p = instance.load(std::memory_order_relaxed);
            if (!p) {
                p = new Singleton();
                instance.store(p, std::memory_order_release);
            }
        }
        return *p;
    }
};

不使用atomic的问题:new Singleton()包含分配内存+构造+赋值三步,CPU可能重排导致另一线程读取到未构造的指针。acquire-release防止了这种重排。

C++11起更推荐Meyers Singleton,更简洁安全。