C++语法学习笔记四十八:单例设计模式共享数据分析、解决,call_once

实例代码:

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}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

C++语法学习笔记四十八:单例设计模式共享数据分析、解决,call_once - HelloWorld