一、单例设计模式共享数据例子
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; // 类的静态变量在类外初始化