• 单例模式的无锁实现


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

      该方法主要使用的是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.
    "); }
    };

      

  • 相关阅读:
    WPF之触发器
    WP之样式
    SqlServer2012——多表连接查询
    SqlServer2012——Select,分组,排序、插入
    sqlserver——视图
    SqlServer规则
    SqlServer自定义数据类型
    SqlServer2012——表
    ES基础使用
    ELK安装
  • 原文地址:https://www.cnblogs.com/jlyg/p/14458346.html
Copyright © 2020-2023  润新知