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;
  • 相关阅读:
    在pos:a元素不设定宽度的情况下,他的最大宽度是受父元素的宽度所限制的。
    跳过权限检查,强制修改mysql密码
    IIS7.5 配置ASP+ACCESS使用环境(转)
    windows 2008配置运行PHP5.5.X
    Content encoding error问题解决方法
    ubuntu 中文显示乱码问题 (转)
    Ubuntu 12.04中文输入法的安装(zhuan)
    html5开发之viewport使用
    Windows/Linux 环境搭建Git服务器 + vs2012集成git
    Windows+VS+SVN实现版本控制
  • 原文地址:https://www.cnblogs.com/LCCRNblog/p/5671854.html
Copyright © 2011-2022 走看看