C++ 线程安全的单例模式

发表于2016-02-11
评论4 3.5k浏览
废话不多说,常用的代码积淀下来。
一、懒汉模式
  即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例。需要用锁,来保证其线程安全性:原因:多个线程可能进入判断是否已经存在实例的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;
}

2、内部静态实例的懒汉模式
  这里需要注意的是,C++0X以后,要求编译器保证内部静态变量的线程安全性,可以不加锁。但C++ 0X以前,仍需要加锁。
lass SingletonInside
{
private:
    SingletonInside(){}
public:
    static SingletonInside* getInstance()
    {
        Lock(); 
// not needed after C++0x
        static SingletonInside instance;
        UnLock(); 
// not needed after C++0x
        return instance; 
    }
};

二、饿汉模式
  即无论是否调用该类的实例,在程序开始时就会产生一个该类的实例,并在以后仅返回此实例。
  由静态初始化实例保证其线程安全性,WHY?因为静态实例初始化在程序开始时进入主函数之前就由主线程以单线程方式完成了初始化,不必担心多线程问题。故在性能需求较高时,应使用这种模式,避免频繁的锁争夺。
class SingletonStatic
{
private:
    static const SingletonStatic* m_instance;
    SingletonStatic(){}
public:
    static const SingletonStatic* getInstance()
    {
        return m_instance;
    }
}; 
//外部初始化 before invoke main
const SingletonStatic* SingletonStatic::m_instance = new SingletonStatic;

  加入GAD的核心用户QQ群:484290331,各类活动奖励任你拿,最新资讯任你读,众多教学任你免费学,如此好地方赶紧加入吧!另VR专属群:476511561,专业VR技术分享,专业导师指导为你答疑解惑,大型小型活动奖励等你拿,免费学习赚奖励的天地,欢迎你加入哟!

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引