zoukankan      html  css  js  c++  java
  • C++线程安全的单例模式

    转载:http://www.cnblogs.com/ccdev/archive/2012/12/19/2825355.html

    一、懒汉模式:即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例。

    需要用锁,来保证其线程安全性:原因:多个线程可能进入判断是否已经存在实例的if语句,从而non thread safety.

    使用double-check来保证thread safety.但是如果处理大量数据时,该锁才成为严重的性能瓶颈。

    1、静态成员实例的懒汉模式:

    class Singleton
    {
    private:
        static Singleton* m_instance;
        Singleton(){}
    public:
        static Singleton* getInstance();
    };
    
    Singleton* Singleton::getInstance()
    {
        if(NULL == m_instance)
        {
            Lock();//借用其它类来实现,如boost
            if(NULL == m_instance)
            {
                m_instance = new Singleton;
            }
            UnLock();
        }
        return m_instance;
    }
    //上面的代码getInstance我觉得第一个if是很有必要,如果改为如下方式,不管m_instance 有没有创建好都会去参与锁的竞争,会严重降低效率,因此第一个if是很有必要的
    Singleton* Singleton::getInstance()
    {
          
            Lock();//借用其它类来实现,如boost
            if(NULL == m_instance)
            {
                m_instance = new Singleton;
            }
            UnLock();
       
        return m_instance;
    }

    2、内部静态实例的懒汉模式

    这里需要注意的是,C++0X以后,要求编译器保证内部静态变量的线程安全性,可以不加锁。但C++ 0X以前,仍需要加锁。

     1 class SingletonInside
     2 {
     3 private:
     4     SingletonInside(){}
     5 public:
     6     static SingletonInside* getInstance()
     7     {
     8         Lock(); // not needed after C++0x
     9         static SingletonInside instance;
    10         UnLock(); // not needed after C++0x
    11         return instance; 
    12     }
    13 };

    二、饿汉模式:即无论是否调用该类的实例,在程序开始时就会产生一个该类的实例,并在以后仅返回此实例。

    由静态初始化实例保证其线程安全性,WHY?因为静态实例初始化在程序开始时进入主函数之前就由主线程以单线程方式完成了初始化,不必担心多线程问题。

    故在性能需求较高时,应使用这种模式,避免频繁的锁争夺。

     1 class SingletonStatic
     2 {
     3 private:
     4     static const SingletonStatic* m_instance;
     5     SingletonStatic(){}
     6 public:
     7     static const SingletonStatic* getInstance()
     8     {
     9         return m_instance;
    10     }
    11 };
    12 
    13 //外部初始化 before invoke main
    14 const SingletonStatic* SingletonStatic::m_instance = new SingletonStatic;
  • 相关阅读:
    关于JSON可能出现的错误,待更/todo
    mongoose的安装与使用(书签记录) 2017
    HTTP的学习记录3--HTTPS和HTTP
    HTTP的学习记录(二)头部
    HTTP(一)概述
    LeetCode 455. Assign Cookies
    LeetCode 453. Minimum Moves to Equal Array Elements
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 447. Number of Boomerangs
    LeetCode 416. Partition Equal Subset Sum
  • 原文地址:https://www.cnblogs.com/LCCRNblog/p/5671854.html
Copyright © 2011-2022 走看看