ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

单件模式

2019-06-21 19:38:11  阅读:259  来源: 互联网

标签:std Singleton 单件 nullptr 模式 instance thread2 thread1


Single.cpp

class Singleton{
private:
    Singleton(); //构造函数
    Singleton(const Singleton& other);  //拷贝构造函数
public:
    static Singleton* getInstance();
    static Singleton* m_instance;
};

Singleton* Singleton::m_instance = nullptr;
//线程非安全版本
Singleton* Singleton::getInstance()
{
    if (m_instance == nullptr){
        m_instance = new Singleton();
    }
    return m_instance;
}

/*
该写法在单线程里是OK的,但是在多线程下就不行
例如有两个thread,thread1和thread2
如果thread1执行到了14行但是没有执行到第15行,恰巧此时的thread2页执行到了
第14行,这就意味着接下里第15行都会被thread1和thread2执行,在多线程的情况下就
会出现被创建两个对象,所以这是一个多线程非安全的版本
*/

//线程安全版本,但锁的代价过高
Singleton* Singleton::getInstance(){
    Lock lock;
    if (m_instance == nullptr)
    {
        m_instance = new Singleton();
    }
    return m_instance;
}

/*
该方法加了一个锁,在thread1在进入该代码后,在锁未释放前,thread2不会
执行到第30行代码,但是锁的代价太高
假如第31行不是空,thread1执行到了第31行,而thread2此时进不了29行,因为thread1锁还没有释放,
那么这个过程有没有必要加锁?
其实没有必要的,读的过程没有必要加锁的,因此在读的过程加锁,是浪费的。
将它放在高并发的场景下,那么锁的代价是非常高的
*/

//双检查锁,但由于内存读写reorder不安全
Singleton* Singleton::getInstance()
{
    if (m_instance == nullptr){
        Lock lock;
        if (m_instance == nullptr)
        {
            m_instance = new Singleton();
        }
    }
    return m_instance;
}
/*
该方法的特点是在锁前在检查一次
锁前检查避免了如果都是读取的时候,也就是m_instance不是nullptr的时候,
出现代价过高的问题
锁后检查是避免thread1和thread2进入51行之后,在52行之前,创建两个对象的
错误。
*/

//C++ 11版本之后 跨平台实现(volatile)
std::atomic<Singleton> Singleton::m_instance;
std::mutex Singleton::m_mutex;

Singleton* Singleton::getInstance(){
    Singleton* tmp = m_instance.load(std::memory_order_relaxed);
    std::atomic_thread_fence(std::memory_order_acquire);//获取内存fence
    if (tmp == nullptr)
    {
        std::lock_guard<std::muutex> lock(m_mutex);
        tmp = m_instance.load(std::memory_order_relaxed);
        if (tmp == nullptr)
        {
            tmp = new Singleton;
            std::atomic_thread_fence(std::memory_order_release);//释放内存fence
            m_instance.store(tmp,std::memory_order_relaxed);
        }
    }

}

 

标签:std,Singleton,单件,nullptr,模式,instance,thread2,thread1
来源: https://www.cnblogs.com/zhuifeng-mayi/p/11066452.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有