当前位置: 首页 > 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.互联网内容的挑战 搜索引擎…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...