单例设计模式-共享数据问题

一、单例设计模式共享数据例子

std::mutex myTutex;

class UniqueElement
{
public:
    static UniqueElement* GetInstance()
    {
        if (m_instacne == nullptr)   // 双重检测,提高程序运行效率
        {
            std::unique_lock<std::mutex> myLock(myTutex);  // 只有m_instacne 为空时,才去加锁
            if (m_instacne == nullptr)      // 等拿到锁之后,再判断m_instacne 是否为空,
            {                               //因为在等待的过程中,m_instacne 会被其他的线程初始化
                m_instacne = new UniqueElement();
            }
        }
        return m_instacne;
    }

public:
    UniqueElement() {}
    static UniqueElement* m_instacne;
};

UniqueElement* UniqueElement::m_instacne = nullptr;   // 类的静态变量在类外初始化

二、std::call_once()

std::call_once();  // 该函数的第二个参数是一个函数名 假设函数名为 a()
// 功能能够保证函数 a() 只被调用一次
// 具备互斥量这种能力,比互斥量消耗资源更少
// 需要与一个标记结合使用,std::once_flag 可以看成是结构体
// call_once() 调用 a() 函数成功之后,就会把这个标记设置为一种已调用状态

std::mutex myTutex;
std::once_flag myFlag;   // 系统定义的一个标记

class UniqueElement
{
public:
    static void CreateInstance()
    {  // 把只被执行一次的代码,放到一个函数中
        m_instacne = new UniqueElement();  
    }
    static UniqueElement* GetInstance()
    {
        std::call_once(myFlag, CreateInstance);  // 保证CreateInstance 只被执行一次
        // 当两个线程同时执行到这里,其中一个线程要等另外一个线程执行完毕CreateInstance 函数
        // 等CreateInstance 执行完,另外的线程才会根据myFlag 的状态,决定是否执行CreateInstance
        return m_instacne;
    }
public:
    UniqueElement() {}
    static UniqueElement* m_instacne;
};

UniqueElement* UniqueElement::m_instacne = nullptr;   // 类的静态变量在类外初始化

 

posted @ 2020-06-26 13:38  min_zhi  阅读(248)  评论(0编辑  收藏  举报