单例模式

参考博客

第一种写法:

这种方法又叫做 Meyers' SingletonMeyer's的单例, 是著名的写出《Effective C++》系列书籍的作者 Meyers 提出的。所用到的特性是在C++11标准中的Magic Static特性:

If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
如果当变量在初始化的时候,并发同时进入声明语句,并发线程将会阻塞等待初始化结束。

这样保证了并发线程在获取静态局部变量的时候一定是初始化过的,所以具有线程安全性。

第二种写法

智能指针和双检锁
shared_ptr和mutex都是C++11的标准,以上这种方法的优点是

  1. 基于 shared_ptr, 用了C++比较倡导的 RAII思想,用对象管理资源,当 shared_ptr 析构的时候,new 出来的对象也会被 delete掉。以此避免内存泄漏。
  2. 加了锁,使用互斥量来达到线程安全。这里使用了两个 if判断语句的技术称为双检锁;好处是,只有判断指针为空的时候才加锁,避免每次调用 get_instance的方法都加锁,锁的开销毕竟还是有点大的。
  • 不足之处在于: 使用智能指针会要求用户也得使用智能指针,非必要不应该提出这种约束; 使用锁也有开销; 同时代码量也增多了,实现上我们希望越简单越好。

第三种写法

智能指针和call_once
同上

#include 
#include 
#include 
#include 
using namespace std;

//------------------------------------局部静态成员变量---------------------------------//
//如果当静态局部变量在初始化的时候,并发同时进入声明语句,并发线程将会阻塞等待初始化结束。
//这样保证了并发线程在获取静态局部变量的时候一定是初始化过的,所以具有线程安全性。
/*
class Singleton{
private:
    Singleton() {
        cout << "constructor" << endl;
    }
    
    
public:
    ~Singleton() {
        cout << "deconstructor" << endl;
    }
    static Singleton & getInstance() {
        static Singleton instance;
        return instance;
    }
};
*/
//---------------------------------局部静态成员变量 end-------------------------------------------//

//------------------------------------双检锁---------------------------------//
/*
class Singleton { //双检锁
private:
    Singleton() {
        cout << "constructor" << endl;
    }

public:
    typedef std::shared_ptr Ptr;
    ~Singleton() {
        cout << "deconstructor" << endl;
    }
    static std::shared_ptr getInstance() {
        if (m_instance_ptr == nullptr) { //只有判断指针为空的时候才加锁,避免每次调用 getInstance的方法都加锁
            std::lock_guard lg(m_mutex);
            if (m_instance_ptr == nullptr) {
                m_instance_ptr = std::shared_ptr(new Singleton);
            }
            return m_instance_ptr;
        }
    }

private:
    static std::shared_ptr m_instance_ptr;
    static std::mutex m_mutex;
};
//静态成员变量的初始化
Singleton::Ptr Singleton::m_instance_ptr = nullptr;
std::mutex Singleton::m_mutex;
*/
//--------------------------------------双检锁 end---------------------------------------------//

//------------------------------------call_once start-------------------------------------//
std::once_flag  s_flag;

class Singleton { 
private:
    Singleton() {
        cout << "constructor" << endl;
    }
    static void createInstance() {
        m_instance_ptr = std::shared_ptr(new Singleton); 
    }

public:
    typedef std::shared_ptr Ptr;
    ~Singleton() {
        cout << "deconstructor" << endl;
    }
    static std::shared_ptr getInstance() {
        std::call_once(s_flag, createInstance);
        return m_instance_ptr;
    }

private:
    static std::shared_ptr m_instance_ptr;
};
//静态成员变量的初始化
Singleton::Ptr Singleton::m_instance_ptr = nullptr;

//------------------------------------call_once end--------------------------------------//



void mythread() {
    cout << "child thread start" << endl;
    //Singleton& instance = Singleton::getInstance(); //类内静态成员变量
    //Singleton::Ptr instance = Singleton::getInstance();  //双检锁
    Singleton::Ptr instance = Singleton::getInstance();  //call_once
    cout << "child thread end" << endl;
}

int main() {
    std::thread my_thread_1(mythread);
    std::thread my_thread_2(mythread);
    my_thread_1.join();
    my_thread_2.join();

    return 0;
}

你可能感兴趣的:(单例模式)