zoukankan      html  css  js  c++  java
  • 单例模式的无锁实现

      在开发过程中经常会遇到单例模式,该模式是工作中最常见的设计模式,简单易用是它的特点。单例一般是通过刚开始就申请内存或者用时申请内存的方式实现,用时动态申请内存的话需要加锁,现在主流的也是双重检测加锁的方式。但是今天要讲的是无锁的方式来完成线程安全的实现。

      该方法主要使用的是CAS的原理,std::atomic就是cas的原子操作类,代码中使用compare_exchange_strong进行更新单例,如果失败会把pCurNode(期待值)改为最新值,如果成功,就是把pNewNode设置进去。为什么不用compare_exchange_weak呢,因为可能为有概率失败,在没有循环的时候,使用compare_exchange_strong比较好,如果在循环中则用compare_exchange_weak比较好。

      

      代码原创:

    #include <atomic>
    template<class _Ty>
    class CSingleton
    {
    public:
        static _Ty* GetInstance();
    protected:
        CSingleton() {}
        CSingleton(const CSingleton& that){}
        CSingleton& operator=(const CSingleton& that) { return *this; }
        ~CSingleton() {}
    };
    
    template<class _Ty>
    _Ty* CSingleton<_Ty>::GetInstance()
    {
        static std::atomic<_Ty*> _atmInstance;
        _Ty* pCurNode = _atmInstance.load();
        if (pCurNode == NULL)
        {
            _Ty* pNewNode = new _Ty;
            _atmInstance.compare_exchange_strong(pCurNode, pNewNode);
            if (pCurNode != NULL)
            {
                //说明其他线程已经更新了
                delete pNewNode;
            }
            else
            {
                pCurNode = pNewNode;
            }
        }
        return pCurNode;
    }

      使用模板方式,这样其他类可以通过继承来实现单例,而不用每次自己都要写一遍。下面是用法代码。

    class A :public CSingleton<A>
    {
    public:
        void Pint() { printf("A is Instance.
    "); }
    };

      

  • 相关阅读:
    mysql主从配置
    apache+mysql+php,安装整合配置。
    [转载]误将SELINUXTYPE看成SELINUX后,将其值改为disabled。导致操作系统服务启动,无法进入单用户模式
    python-趣味百题3
    python-趣味百题2
    python-趣味百题1
    python之路----1
    控件的textIsSelectable属性引起的血案
    导入eclipse项目 编码格式错误,运行包 不能映射的...编码
    Glide 缓存使用
  • 原文地址:https://www.cnblogs.com/jlyg/p/14458346.html
Copyright © 2011-2022 走看看