实例代码:
1// 2 3#include <iostream> 4#include <vector> 5#include <thread> 6#include <mutex> 7 8using namespace std; 9 10 11class A{ 12public: 13}; 14 15std::mutex resource_mutex; 16std::once_flag g_flag; //这是个系统定义的标记 17 18 19class MyCAS{ //这是一个单例类 20 21 static void CreateInstance(){ //只被调用1次 22 m_instance = new MyCAS(); 23 static CGarhuishou c1; 24 } 25 26 27private: 28 MyCAS(){} //私有化了构造函数 29 30private: 31 static MyCAS * m_instance; //静态成员变量 32 33public: 34 static MyCAS *GetInstance(){ 35 36 //提高效率 37 //a) 如果if (m_instance != nullptr) 条件成立,则肯定表示 m_instance 已经被new过了 38 //b) 如果if (m_instance == nullptr) 不代表m_instance一定没被new过 39 40 //if (m_instance == nullptr) //双重锁定(双重检查) 41 //{ 42 // std::unique_lock<std::mutex> mymutex(resource_mutex); //自动加锁 43 // if (m_instance == nullptr) 44 // { 45 // m_instance = new MyCAS(); 46 // static CGarhuishou c1; 47 // } 48 //} 49 std::call_once(g_flag, CreateInstance); //两个线程同时执行到这里,其中一个线程要等另外一个线程执行完毕CreateInstance(); 50 cout << "call_once()执行完毕" << endl; 51 return m_instance; 52 } 53 54 class CGarhuishou //类中套类,用来释放对象 55 { 56 public: 57 ~CGarhuishou(){ //类的析构函数中 58 if (MyCAS::m_instance) 59 { 60 delete MyCAS::m_instance; 61 MyCAS::m_instance = NULL; 62 } 63 } 64 }; 65 66 67 void func(){ 68 cout << "测试" << endl; 69 } 70}; 71 72MyCAS * MyCAS::m_instance = nullptr; 73 74 75//线程入口函数 76void mythread(){ 77 cout << "我的线程开始执行了" << endl; 78 MyCAS *p_a = MyCAS::GetInstance(); //这里可能就有问题了 79 p_a->func(); 80 cout << "我的线程执行完毕了" << endl; 81 return; 82} 83 84int main() 85{ 86 //一:设计模式大概谈 87 //"设计模式":代码的一些写法(这些写法跟常规写法还不怎么一样):程序灵活,维护起来可能方便,但是别人接管、阅读代码都很痛苦。 88 //用“设计模式”理念写出来的代码很晦涩的 89 //老外 应付特别大的项目的时候,把项目的开发经验、模块划分经验,总结整理成设计模式(现有开发需求,后有理论总结和整理) 90 //设计模式拿到中国来,不太一样,拿着一个程序(项目)往设计模式上套;一个小小的项目,它非要弄几个设计模式进去;本末倒置。 91 //设计模式肯定有它独特的优点,要活学活用,不要深陷其中,生搬硬套; 92 93 94 //二:单例设计模式 95 //单例设计模式,使用的频率比较高; 96 //单例:整个项目中,有某个或者某些特殊的类,属于该类的对象,我只能创建1个,多了我创建不了; 97 //单例类: 98 A a1; 99 A a2; 100 101 //MyCAS a; 102 MyCAS *p_a = MyCAS::GetInstance(); //创建一个对象,返回该类(MyCAS)对象的指针 103 p_a->func(); 104 105 //三:单例设计模式共享数据问题分析、解决 106 //面临的问题:需要在我们自己创建的线程(而不是主线程)中来创建MyCAS这个单例类的对象,这种线程可能不止(最少2个)。 107 //我们可能会面临GetInstance()这种成员函数要互斥 108 109 //虽然这两个线程是同一个入口函数,但大家千万要记住,这是两个线程,所以这里会有两个流程(两条通路)同时开始执行mythread这个函数; 110 std::thread mytobj1(mythread); 111 std::thread mytobj2(mythread); 112 113 mytobj1.join(); 114 mytobj2.join(); 115 116 117 //四:std::call_once();C++11引入的函数,该函数的第二个参数是一个函数名 a(); 118 //call_once 功能是能够保证函数a()只被调用一次 119 //call_once 具备互斥量这种能力,而且效率上,比互斥量消耗的资源更少; 120 //call_once()需要与一个标记结合使用,这个标记 std::once_flag;其实once_flag是一个结构; 121 //call_once()就是通过这个标记来决定对应的函数a()是否执行,调用call_once成功后,call_once()就把这个标记设置为一种已调用状态 122 //后续再次调用call_once() ,只要once_flag被设置为了“已调用”状态,那么对应的函数a()就不会再被执行了; 123 124 125 126 system("pause"); 127}