双重检查锁(DCLP)
- 通过 std::mutex 保证线程安全
- 双重检查减少了锁的开销,只有第一次创建时才会加锁
cpp
#include <iostream>
#include <mutex>
class Singleton {
private:
static Singleton* instance;
static std::mutex mtx;
// 私有构造函数,禁止外部创建
Singleton() {
std::cout << "Constructor called\n";
}
public:
// 删除拷贝和赋值,防止拷贝产生多个实例
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* getInstance() {
if (instance == nullptr) { // 第一次检查
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) { // 第二次检查
instance = new Singleton();
}
}
return instance;
}
void show() {
std::cout << "Singleton instance address: " << this << "\n";
}
};
// 静态成员初始化
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
s1->show();
s2->show();
return 0;
}
静态局部变量
- C++11 标准保证静态局部变量的初始化是线程安全的
- 不需要手动加锁
cpp
#include <iostream>
class Singleton {
private:
Singleton() {
std::cout << "Constructor called\n";
}
public:
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton& getInstance() {
static Singleton instance; // C++11 保证线程安全
return instance;
}
void show() {
std::cout << "Singleton instance address: " << this << "\n";
}
};
int main() {
Singleton& s1 = Singleton::getInstance();
Singleton& s2 = Singleton::getInstance();
s1.show();
s2.show();
return 0;
}