在c++++中,线程安全的单例模式推荐使用局部静态变量实现,因为c++11保证了静态局部变量初始化的线程安全性,该方法无需手动加锁、代码简洁且自动管理生命周期;若需延迟初始化或传参构造,可采用双重检查锁定结合std::mutex和智能指针的方式,通过外层if减少锁竞争,内层if确保唯一实例创建,利用std::unique_ptr或std::shared_ptr避免内存泄漏;需注意双重检查中两次判空缺一不可,防止竞态条件和性能下降,同时避免裸new和手动delete,优先使用raii机制管理资源,确保在多线程环境下安全可靠地创建唯一实例。

在C++中,单例模式(Singleton Pattern)是一种常见的设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。在多线程环境下,必须保证单例的构造是线程安全的。双重检查锁定(Double-Checked Locking Pattern, DCLP)是一种常用的实现方式,但需要小心处理以避免竞态条件。
下面介绍如何实现一个线程安全的单例模式,重点讲解双重检查锁定的正确写法。
从 C++11 开始,标准引入了静态局部变量的线程安全性保证,这使得实现线程安全单例变得非常简单。但如果你仍想使用双重检查锁定(比如需要延迟初始化且不依赖静态变量),可以如下实现:
立即学习“C++免费学习笔记(深入)”;
#include <mutex>
class Singleton {
public:
// 获取单例实例
static Singleton* getInstance() {
// 第一次检查:避免不必要的加锁
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mutex_);
// 第二次检查:确保只有一个线程创建实例
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
// 禁用拷贝构造和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() = default; // 私有构造函数
static Singleton* instance;
static std::mutex mutex_;
};
// 静态成员定义
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex_;if
⚠️ 注意:在 C++11 之前,这种写法可能因为内存模型问题存在风险(如指令重排导致返回未完全构造的对象)。但在 C++11 及以后,只要使用 std::mutex,配合编译器的内存屏障,是安全的。
C++11 标准规定:函数内的静态局部变量初始化是线程安全的。这是最简洁、最安全的单例实现方式。
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // 线程安全,C++11 起保证
return instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() = default;
};getInstance()
如果你需要动态创建且希望自动管理内存,可以使用
std::unique_ptr
std::shared_ptr
#include <mutex>
#include <memory>
class Singleton {
public:
static Singleton& getInstance() {
if (!instance) {
std::lock_guard<std::mutex> lock(mutex_);
if (!instance) {
instance = std::make_unique<Singleton>();
}
}
return *instance;
}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() = default;
static std::unique_ptr<Singleton> instance;
static std::mutex mutex_;
};
std::unique_ptr<Singleton> Singleton::instance = nullptr;
std::mutex Singleton::mutex_;注意:返回的是引用,但内部用指针管理。析构仍需注意,
在程序结束时会自动释放。unique_ptr登录后复制
if
new
new
mutex
atomic
std::mutex
new
delete
基本上就这些,不复杂但容易忽略细节。
以上就是C++单例模式如何实现 线程安全版本与双重检查锁定的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号