头图
  • 概念

    • 程序的生命周期内只有一个实例的存在
  • 场景

    • 日志记录器、数据库连接池、线程池等
  • 实现

    #include <iostream>
    #include <mutex>
    #include <boost/noncopyable.hpp>
    
    using namespace std;
    
    // 版本一
    // 创建即初始化-eager initialize
    // 不过需要提前初始化。但是从生产环境考虑,单例模式必须创建,同时需要系统预热。
    // 因此该版本也具有一定的适用性。
    class Singleton : public boost::noncopyable{
    private:
        shared_ptr<Singleton> sp_instance;
        
    private:
        Singleton() = default;
        
    public:
        // 智能指针的析构函数需要对象的析构函数的访问权限
        ~Singleton() = default;
        
        static weak_ptr<Singleton> GetInstance() {
            return sp_instance;
        }
    };
    
    shared_ptr<Singleton> Singleton::sp_instance(new Singleton);
    #include <iostream>
    #include <mutex>
    #include <boost/noncopyable.hpp>
    
    using namespace std;
    // 以下几个版本为用时创建,Lazy模式。
    // 版本二
    // 会出现写放大(A进程创建智能指针A并赋值给静态单例变量,
    // 此时发生进程切换,B进程创建智能指针B并赋值给单例变量,因此A进程创建的智能指针A自动销毁)。
    // 总的来说,能够正确创建并返回对象,但是初始会多创建一次浪费资源
    class Singleton : public boost::noncopyable{
    private:
      Singleton() = default;
      
    public:
      // 智能指针需要调用
      ~Singleton() = default;
      
      static weak_ptr<Singleton> GetInstance() {
          static shared_ptr<Singleton> sp_singleton = 
              shared_ptr<Singleton> (new Singleton());
          return sp_singleton;
      }
    };
    // 版本三
    // 先上锁->并发退化成串行。
    // 在写-读场景下并发能力弱。适用于写-写场景。
    class Singleton : public boost::noncopyable{
    private:
       shared_ptr<Singleton> sp_instance;
       mutex_t mutex;
       
    private:
       Singleton() = default;
       
    public:
       // 智能指针需要调用
       ~Singleton() = default;
       
       static weak_ptr<Singleton> GetInstance() {
           mutex.lock();    // RALL
           if (sp_instance == nullptr)
               sp_instance = shared_ptr<Singleton> (new Singleton());
           return sp_singleton;
       }
    };
    // 版本四
    // DCL+volatile关键字->版本三的优化。
    // 通过volatile关键字防止最外层判断出现未完全初始化对象,通过内层加锁保证过程的互斥性。
    // 适合写-读场景。
    class Singleton : public boost::noncopyable{
    private:
      static volatile shared_ptr<Singleton> instance;
      static std::mutex mutex;
    
    private:
      Singleton() = default;
    
    public:
      ~Singleton() {}
      
      static weak_ptr<Singleton> GetInstance() {
          if (instance == nullptr) {
              mutex.lock();
              if (instance == nullptr) {
                  instance = shared_ptr<Singleton> (new Singleton());
              }
          }
          return instance;
      }
    };
    
    
    int main() {
      auto ptr_singleton = Singleton::GetInstance();
      // do something...
    }

kkkK2008
1 声望0 粉丝

« 上一篇
chrono精讲