当前位置: 首页 > news >正文

C++11并发与多线程笔记(7) 单例设计模式共享数据分析、解决,call_once

C++11并发与多线程笔记(7) 单例设计模式共享数据分析、解决,call_once

  • 1.设计模式
  • 2.单例设计模式:
  • 3.单例设计模式共享数据分析、解决
  • 4.std::call_once():

1.设计模式

  • 程序灵活,维护起来可能方便,用设计模式理念写出来的代码很晦涩,但是别人接管、阅读代码都会很痛苦
  • 老外应付特别大的项目时,把项目的开发经验、模块划分经验,总结整理成设计模式
  • 中国零几年设计模式刚开始火时,总喜欢拿一个设计模式往上套,导致一个小小的项目总要加几个设计模式,本末倒置
  • 设计模式有其独特的优点,要活学活用,不要深陷其中,生搬硬套

2.单例设计模式:

整个项目中,有某个或者某些特殊的类,只能创建一个属于该类的对象
单例类:只能生成一个对象。

# include<iostream>
using namespace std;
class MyClass {//单例类
private:MyClass(){}//私有化构造函数static MyClass* m_instance;//静态成员变量
public:static MyClass* getInstance() {//静态成员函数用于创建对象if (m_instance == NULL) {m_instance = new MyClass();}return m_instance;}void func() {cout << "测试" << endl;}};
MyClass* MyClass::m_instance = NULL;//类内定义,类外初始化int main() {//创建一个对象,返回该类(Myclass)对象的指针MyClass* p_a = MyClass::getInstance();p_a->func();//测试
}

如果觉得在单例模式new了一个对象,而没有自己delete掉,这样不合理。可以增加一个类中类CGarhuishou,new一个单例类时创建一个静态的CGarhuishou对象,这样在程序结束时会调用CGarhuishou的析构函数,释放掉new出来的单例对象。

# include<iostream>
using namespace std;
class MyClass {//单例类
private:MyClass(){}//私有化构造函数static MyClass* m_instance;//静态成员变量
public:static MyClass* getInstance() {//静态成员函数用于创建对象if (m_instance == NULL) {m_instance = new MyClass();static CGarhuishou cl; //释放对象}return m_instance;}class CGarhuishou {//类中套类,用来释放对象public:~CGarhuishou() {if (MyClass::m_instance) {delete MyClass::m_instance;MyClass::m_instance = NULL;}}};void func() {cout << "测试" << endl;}};
MyClass* MyClass::m_instance = NULL;//类内定义,类外初始化int main() {//创建一个对象,返回该类(Myclass)对象的指针MyClass* p_a = MyClass::getInstance();p_a->func();//测试
}

3.单例设计模式共享数据分析、解决

面临问题:需要在自己创建的线程(而不是主线程)中来创建单例类的对象,这种线程可能不止一个。我们可能面临getInstance()这种成员函数需要互斥。
解决方法:可以在
加锁前判断m_instance是否为空
,否则每次调用MyClass::getInstance()都要加锁,十分影响效率。

# include<iostream>
# include<thread>
#include<mutex>
using namespace std;
mutex mutex1;
class MyClass {//单例类
private:MyClass(){}//私有化构造函数static MyClass* m_instance;//静态成员变量
public:static MyClass* getInstance() {//双重锁定 提高效率if (m_instance == NULL) {unique_lock<mutex> myMutex(mutex1);//单独加此代码,每一次判断创建新对象,都要加锁if (m_instance == NULL) {m_instance = new MyClass();static CGarhuishou cl;}}return m_instance;}class CGarhuishou {//类中套类,用来释放对象public:~CGarhuishou() {if (MyClass::m_instance) {delete MyClass::m_instance;MyClass::m_instance = NULL;}}};void func() {cout << "测试" << endl;}
};
MyClass* MyClass::m_instance = NULL;//类内定义,类外初始化//线程入口函数
void mythread() {cout << "myPrint线程开始执行了 " << endl;MyClass* p_a = MyClass::getInstance();cout << "myPrint线程结束执行了"  << endl;
}
int main() {thread myobj1(mythread);thread myobj2(mythread);myobj1.join();myobj2.join();
}

4.std::call_once():

函数模板,该函数的第一个参数标记第二个参数是一个函数名(如a())。
功能:能够保证函数a()只被调用一次。具备互斥量的能力,而且比互斥量消耗的资源更少,更高效。

  • call_once()需要与一个标记结合使用,这个标记为std::once_flag;其实once_flag是一个结构,call_once()就是通过标记来决定函数是否执行,调用成功后,就把标记设置为一种已调用状态

  • 多个线程同时执行时,使用call_once(),一个线程会等待另一个线程先执行。

# include<iostream>
# include<thread>
#include<mutex>
using namespace std;
once_flag g_flag;//标记来决定函数是否执行class MyClass {//单例类
private:MyClass() {}//私有化构造函数static MyClass* m_instance;//静态成员变量
public://用于call_once函数的第二个参数,保证其只被调用一次static void CreateInstance() {m_instance = new MyClass;static CGarhuishou cl;}//两个线程同时执行到这里,其中一个线程要等另外一个线程执行完毕static MyClass* getInstance() {call_once(g_flag,CreateInstance);return m_instance;}class CGarhuishou {//类中套类,用来释放对象public:~CGarhuishou() {if (MyClass::m_instance) {delete MyClass::m_instance;MyClass::m_instance = NULL;}}};void func() {cout << "测试" << endl;}
};
MyClass* MyClass::m_instance = NULL;//类内定义,类外初始化//线程入口函数
void mythread() {cout << "myPrint线程开始执行了 " << endl;MyClass* p_a = MyClass::getInstance();cout << "myPrint线程结束执行了"  << endl;
}
int main() {thread myobj1(mythread);thread myobj2(mythread);myobj1.join();myobj2.join();
}

相关文章:

C++11并发与多线程笔记(7) 单例设计模式共享数据分析、解决,call_once

C11并发与多线程笔记&#xff08;7&#xff09; 单例设计模式共享数据分析、解决&#xff0c;call_once 1.设计模式2.单例设计模式&#xff1a;3.单例设计模式共享数据分析、解决4.std::call_once()&#xff1a; 1.设计模式 程序灵活&#xff0c;维护起来可能方便&#xff0c;…...

FANUC机器人加减速倍率指令ACC的使用方法说明

FANUC机器人加减速倍率指令ACC的使用方法说明 单位有一台FANUC机器人(型号:M-900iB 360kg),偶尔会在启动的瞬间会报SRVO-050碰撞检测报警,而事实上机器人并没有开始移动或和其他工件产生碰撞,一直查了很长时间,也没有查到具体的原因,也尝试过重新进行负载推算,但是偶尔…...

奥威BI数据可视化工具:360度呈现数据,告别枯燥表格

随着企业数据量的不断增加&#xff0c;如何有效地进行数据分析与决策变得越来越重要。奥威BI数据可视化工具作为一款强大的数据分析工具&#xff0c;在帮助企业深入挖掘数据价值方面具有显著优势。 奥威BI数据可视化工具是一款基于数据仓库技术的数据分析工具&#xff0c;具有…...

C# Linq源码分析之Take (三)

概要 本文在前两篇Take源码分析的基础上&#xff0c;着重分析Range参数中有倒数的情况&#xff0c;即分析TakeRangeFromEndIterator的源码实现。 源码及分析 TakeRangeFromEndIterator方法用于处理Range中的开始和结束索引存在倒数的情况。该方法位于Take.cs文件中。通过yie…...

Linux journalctl命令详解(journalctl指令)(systemd服务默认日志管理工具)

文章目录 Linux Journalctl命令详解1. Journalctl简介2. Journalctl基础使用3. 过滤日志条目4. 时间戳和日志轮转5. 高级应用6. journalctl --help指令文档英文中文 注意事项journal日志不会将程序输出的空行显示&#xff0c;日志会被压缩得满满当当。journal日志不会自动持久化…...

学习内容--

C后台开发_c做后台_人面桃花相映红的博客-CSDN博客 C/C后端开发学习路线总结&#xff08;附带实习学习经历分享&#xff09;_c后端开发需要学什么_Linux后台开发狮的博客-CSDN博客 学到什么程度才可以面试大厂&#xff1f;c/c后台开发进阶指南 后端开发&#xff08;超全&…...

Stable Diffusion:使用自己的数据集微调训练LoRA模型

Stable Diffusion&#xff1a;使用自己的数据集微调训练LoRA模型 前言前提条件相关介绍微调训练LoRA模型下载kohya_ss项目安装kohya_ss项目运行kohya_ss项目准备数据集生成关键词模型参数设置预训练模型设置文件夹设置训练参数设置 开始训练LoRA模型TensorBoard查看训练情况 测…...

软考高级系统架构设计师系列之:论文典型试题写作要点和写作素材总结系列文章一

软考高级系统架构设计师系列之:论文典型试题写作要点和写作素材总结系列文章一 一、论软件体系结构风格及其应用1.论文题目2.写作要点和写作素材二、论开放系统应用的互操作性技术1.论文题目2.写作要点和写作素材三、论多层分布结构系统的开发1.论文题目2.写作要点和写作素材四…...

06 mysql all查询 和 主键查询 和 非索引列查询

前言 本文主要调试一下 mysql 的如下两种查询语句 我们也来深入的看一下, 究竟如下两个普通的查询, mysql 做了什么事情 1. select * from user where id 991; 2. select * from user; 3. select * from user where name jerry991; 环境介绍 测试表 user schema 如下…...

黑马点评-项目集成git及redis实现短信验证码登录

目录 IDEA集成git 传统session存在的问题 redis方案 业务流程 选用的数据结构 整体访问流程 发送短信验证码 获取校验验证码 配置登录拦截器 拦截器注册配置类 拦截器 用户状态刷新问题 刷新问题解决方案 IDEA集成git 远程仓库采用码云&#xff0c;创建好仓库&…...

mac苹果电脑怎么运行Windows软件?怎么安装Win虚拟机?

近年来&#xff0c;苹果电脑的用户群体不断扩大&#xff0c;许多用户对于苹果电脑是否可以运行Windows软件产生了疑问。苹果电脑和Windows操作系统有着明显的区别&#xff0c;是否能够在苹果电脑上运行Windows软件。下面我们就来看苹果电脑可以运行Windows软件吗&#xff0c;苹…...

Jmeter对websocket进行测试

JMeterWebSocketSampler-1.0.2-SNAPSHOT.jar下载 公司使用websocket比较奇怪&#xff0c;需要带认证信息进行长连接&#xff0c;通过websocket插件是请求失败&#xff0c;如下图&#xff0c;后面通过代码实现随再打包jar包完成websocket测试 本地实现代码如下&#xff1a; pa…...

从2023年世界机器人大会发现机器人新趋势

机器人零部件为何成2023年世界机器人大会关注热门&#xff1f; 在原先&#xff0c;机器人的三大核心零部件是控制系统中的控制器、驱动系统中的伺服电机和机械系统中的精密减速器。如今&#xff0c;机器人的主体框架结构已经落实&#xff0c;更多机器人已经开始深入到各类场景中…...

Kafka单节点部署

&#x1f388; 作者&#xff1a;互联网-小啊宇 &#x1f388; 简介&#xff1a; CSDN 运维领域创作者、阿里云专家博主。目前从事 Kubernetes运维相关工作&#xff0c;擅长Linux系统运维、开源监控软件维护、Kubernetes容器技术、CI/CD持续集成、自动化运维、开源软件部署维护…...

生成式AI和大语言模型 Generative AI LLMs

在“使用大型语言模型(LLMs)的生成性AI”中&#xff0c;您将学习生成性AI的基本工作原理&#xff0c;以及如何在实际应用中部署它。 通过参加这门课程&#xff0c;您将学会&#xff1a; 深入了解生成性AI&#xff0c;描述基于LLM的典型生成性AI生命周期中的关键步骤&#xff…...

Obsidian 入门使用手册

文章目录 一、Obsidian 入门1.1 什么是 Obsidian1.2 安装 Obsidian 二、Obsidian 配置2.1 创建第一个笔记2.2 设置界面语言使用中文2.3 主题 三、小结 一、Obsidian 入门 1.1 什么是 Obsidian Obsidian 是一款基于 Markdown 语法编辑的笔记软件。与传统的 Markdown 软件不同的…...

GuLi商城-前端基础Vue指令-单向绑定双向绑定

什么是指令? 指令 (Directives) 是带有 v- 前缀的特殊特性。 指令特性的预期值是:单个 JavaScript 表达式。 指令的职责是&#xff0c;当表达式的值改变时&#xff0c;将其产生的连带影响&#xff0c;响应式地作用于DOM 例如我们在入门案例中的 v-on&#xff0c;代表绑定事…...

前端(十三)——JavaScript 闭包的奥秘与高级用法探索

&#x1f636;博主&#xff1a;小猫娃来啦 &#x1f636;文章核心&#xff1a;深入理解 JavaScript 中的闭包 文章目录 不理解闭包&#xff1f;这玩意很难&#xff1f;闭包的定义与原理闭包是什么创建一个闭包 闭包的应用场景闭包与作用域闭包与作用域之间的关系全局作用域、函…...

面试-快速学习计算机网络-UDP/TCP

1. OSI四层和七层映射 区别&#xff1a; 应用层&#xff0c;表示层&#xff0c;会话层合并为了应用层数据链路层和物理层合并为了网络接口层 2. TCP和UDP的区别&#xff1f; 总结&#xff1a; 1 . TCP 向上层提供面向连接的可靠服务 &#xff0c;UDP 向上层提供无连接不可靠服…...

爱校对如何帮助企业和博客主提高在线可见性?

在数字化时代&#xff0c;内容质量已经成为增强在线曝光率的关键因素。企业和博客主经常面临挑战&#xff0c;如何制作高质量、无误的内容以吸引更多的在线用户。此文将详细分析“爱校对”如何帮助用户优化内容&#xff0c;从而提高在线可见性。 1.互联网内容的挑战 搜索引擎…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”

深入浅出JavaScript中的ArrayBuffer&#xff1a;二进制数据的“瑞士军刀” 在JavaScript中&#xff0c;我们经常需要处理文本、数组、对象等数据类型。但当我们需要处理文件上传、图像处理、网络通信等场景时&#xff0c;单纯依赖字符串或数组就显得力不从心了。这时&#xff…...

Vue.js教学第二十一章:vue实战项目二,个人博客搭建

基于 Vue 的个人博客网站搭建 摘要: 随着前端技术的不断发展,Vue 作为一种轻量级、高效的前端框架,为个人博客网站的搭建提供了极大的便利。本文详细介绍了基于 Vue 搭建个人博客网站的全过程,包括项目背景、技术选型、项目架构设计、功能模块实现、性能优化与测试等方面。…...

【免杀】C2免杀技术(十五)shellcode混淆uuid/ipv6/mac

针对 shellcode 混淆(Shellcode Obfuscation) 的实战手段还有很多,如下表所示: 类型举例目的编码 / 加密XOR、AES、RC4、Base64、Poly1305、UUID、IP/MAC改变字节特征,避开静态签名或 YARA结构伪装PE Stub、GIF/PNG 嵌入、RTF OLE、UUID、IP/MAC看起来像合法文件/数据,弱…...

【HTML】HTML 与 CSS 基础教程

作为 Java 工程师&#xff0c;掌握 HTML 和 CSS 也是需要的&#xff0c;它能让你高效与前端团队协作、调试页面元素&#xff0c;甚至独立完成简单页面开发。本文将用最简洁的方式带你掌握核心概念。 一、HTML&#xff0c;网页骨架搭建 核心概念&#xff1a;HTML通过标签定义内…...

Vue:Form正则校验

目录 1. 只能输入正整数或正小数(保留三位小数) 1. 只能输入正整数或正小数(保留三位小数) cc: [{required: true, message: "钻杆长度不能为空", trigger: "blur" },{pattern: /^\d(\.\d{1,3})?$/, message: 只能输入正整数或正小数(保留三位小数), tri…...

SpringBoot+MySQL家政服务平台 设计开发

概述 基于SpringBootMySQL开发的家政服务平台完整项目&#xff0c;该系统实现了用户预约、服务管理、订单统计等核心功能&#xff0c;采用主流技术栈开发&#xff0c;代码规范且易于二次开发。 主要内容 系统功能架构 本系统采用前后端分离架构&#xff0c;前端提供用户交互…...