单例模式指在整个系统生命周期里,保证一个类只能产生一个实例,确保该类的唯一性。
单例类特点
单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同:
Singleton& Singleton::getInstance() {
static Singleton instance;
return instance;
}
一般推荐使用这种简单的方式,安全好用!
要实现安全的懒汉式不容易
Singleton* Singleton::getInstance() {
if (m_instance)
return m_instance;
Lock lock; // scope-based lock, released automatically when the function returns
if (m_instance == NULL) {
m_instance = new Singleton;
}
return m_instance;
}
严格意义上说,上面的实现方法是不是完全安全的,因为第一次读取m_instance不受锁或类似东西的保护;
std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;
Singleton* Singleton::getInstance() {
Singleton* tmp = m_instance.load();
if (tmp == nullptr) {
std::lock_guard<std::mutex> lock(m_mutex);
tmp = m_instance.load();
if (tmp == nullptr) {
tmp = new Singleton;
m_instance.store(tmp);
}
}
return tmp;
}
#include
#include
#include
#include
#include
class Singleton {
public:
static Singleton* getInstance() {
Singleton* tmp = m_instance.load();
if (tmp == nullptr) {
std::lock_guard<std::mutex> lock(m_mutex);
tmp = m_instance.load();
if (tmp == nullptr) {
tmp = new Singleton;
m_instance.store(tmp);
}
}
return tmp;
}
~Singleton() {
std::cout << "~Singleton() called!" << std::endl;
}
void print() {
if (m_instance == nullptr)
std::cout << "m_instance is null" << std::endl;
else
std::cout << "m_instance is not null" << std::endl;
}
private:
Singleton() = default;
Singleton(const Singleton& Singleton) = default;
static std::atomic<Singleton*> m_instance;
static std::mutex m_mutex;
};
std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;
int main()
{
Singleton::getInstance()->print();
std::thread([]{ Singleton::getInstance()->print(); }).detach();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return 0;
}
输出:
m_instance is not null
m_instance is not null
is-implementation-of-double-checked-singleton-thread-safe
double-checked-locking-is-fixed-in-cpp11
C++11 中的双重检查锁定模式
陈硕智能指针线程安全_linux C++ 线程安全的单例模式总结