单例模式:
- 一个类仅有一个实例
- 提供该实例的全局访问点
单线程下的单例模式:
cpp
class Singleton{
public:
static Singleton * GetInstance(){
if(_instance == nullptr)
{
_instance = new Singleton();
std::atexit(Destructor);
}
return _instance;
}
private:
static void Destructor(){
if(_instance != nullptr){
delete _instance;
_instance = nullptr;
}
}
Singleton() {}
~Singleton() {}
Singleton(const Singleton &clone) {}
Singleton & operator=(const Singleton &) {};
static Singleton *_instance;
};
Singleton *Singleton::_instance = nullptr;
1.静态成员函数和静成员变量
2.构造、析构、赋值操作符、拷贝构造私有化
3.new是堆上创建std::atexit
多线程下的单例模式:
cpp
#include <mutex>
#include <atomic>
class Singleton{
public:
static Singleton * GetInstance(){
Singleton *temp = _instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);//内存栅栏,确保在此点之前的所有读操作都完成,并且在此点之后的所有读操作都不会被重排到这个点之前
//std::lock_guard<std::mutex> lock(_mutex);
if(_instance == nullptr)
{
std::lock_guard<std::mutex> lock(_mutex);
temp = _instance.load(std::memory_order_relaxed);
if(_instance == nullptr)
{
temp = new Singleton();//多线程环境下编译器和cpu对程序进行优化
std::atomic_thread_fence(std::memory_order_release);
_instance.store(temp,std::memory_order_relaxed);
//1.分配内存 2.调用构造函数 3.返回指针、赋值运算
//优化为1、3、2
std::atexit(Destructor);
}
}
return _instance;
}
private:
static void Destructor(){
Singleton *temp = _instance.load(std::memory_order_relaxed);
if(temp != nullptr){
delete temp;
_instance.store(temp,std::memory_order_relaxed);
temp = nullptr;
}
}
Singleton() {}
~Singleton() {}
Singleton(const Singleton &clone) {}
Singleton & operator=(const Singleton &) {};
static std::atomic<Singleton *> _instance;
static std::mutex _mutex;
};
std::atomic<Singleton *> Singleton::_instance = nullptr;
std::mutex Singleton::_mutex;
1.两次判断,希望在第二次判断的时候加互斥锁
2.多线程环境下,编译器、cpu的优化(指令重排)------原子操作+内存屏障
获取更多Linux C/C++资料