c++单例模式和call_once函数
单例模式是一种常见的设计模式,用于确保某个类只能创建一个实例。由于单例模式是全局唯一的,因此在多线程中使用单例模式时需要考虑线程安全问题。
1.GetInstance()实例化一个对象
- 懒汉式:第一次用到类的时候才会去实例化。
懒汉式创建对象的方法是在程序使用对象前,先判断该对象是否已经实例化(判空),若已实例化直接返回该类对象。,否则则先执行实例化操作。
- 饿汉式:在类的加载的时候就去实例化
饿汉式在类加载时已经创建好该对象,在程序调用时直接返回该单例对象即可,即我们在编码时就已经指明了要马上创建这个对象,不需要等到被调用时再去创建。
#include<iostream>
#include<thread>
#include<mutex>
#include<string>class Log {
public:Log() {};Log(const Log& log) = delete;Log& operator = (const Log& log) = delete;static Log& GetIntance(){static Log Log; //饿汉模式,提前声明一个对象,需要的时候直接给。return Log; }/*****************************static Log& GetIntance(){static Log *Log = nullptr; //懒汉模式,需要的时候再去创建一个对象。if(!Log) Log = new Log;return *Log;}
****************************/};void printfLog(std::string msg){std::cout<<msg<<std::endl;
}void func(std::string msg){Log::GetInstance().printLog("error!!!");
}int main(){std::thread t1(func);std::thread t1(func);t1.json;t2.json;Log::GetInstance().printLog("error!!!");
}
==================================
2.多线程出现线程安全问题
t1和t2同时调用func函数,func函数调用GetInstance函数实例化一个对象,但是如果t1和t2同时new一个对象Log,当new的Log对象的地址还没来得及赋值给Log,t2又new了一个对象,这时就会出现错误。
代码实例如下:
#include<iostream>
#include<thread>
#include<mutex>
#include<string>class Log {
public:Log() {};Log(const Log& log) = delete;Log& operator = (const Log& log) = delete;
/***************************** static Log& GetIntance(){static Log Log; //饿汉模式,提前声明一个对象,需要的时候直接给。return Log; }
****************************/static Log& GetIntance(){static Log *Log = nullptr; //懒汉模式,需要的时候再去创建一个对象。if(!Log) Log = new Log;return *Log;}void printfLog(std::string msg){std::cout<<msg<<std::endl;
}};void func(std::string msg){Log::GetInstance().printLog("error!!!");}int main(){std::thread t1(func);std::thread t1(func);t1.json;t2.json;Log::GetInstance().printLog("error!!!");
}
==================================
从性能线程上的区别:
1、线程安全:
饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题。
懒汉式本身是非线程安全的。
2、资源加载和性能:
饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内 存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成。
而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。
================================
3.call_once函数
在多线程中,有一种场景是某个任务只需要执行一次,可以用C++11中的std::call_once函数配合std::once_flag来实现。多个线程同时调用某个函数,std::call_once可以保证多个线程对该函数只调用一 次。
void call_once (once_flag& flag, Fn&& fn, Args&&...args);
第一个参数是std::once_flag的对象(once_flag是不允许修改的,其拷贝构造函数和operator=函数都声明为delete),第二个参数可调用实体,即要求只执行一次的代码,后面可变参数是其参数列表。
call_once保证函数fn只被执行一次,如果有多个线程同时执行函数fn调用,则只有一个活动线程(active call)会执行函数,其他的线程在这个线程执行返回之前会处于”passive execution”(被动执行状态)——不会直接返回,直到活动线程对fn调用结束才返回。对于所有调用函数fn的并发线程,数据可见性都是同步的(一致的)。
如果活动线程在执行fn时抛出异常,则会从处于”passive execution”状态的线程中挑一个线程成为活动线程继续执行fn,依此类推。一旦活动线程返回,所有”passive execution”状态的线程也返回,不会成为活动线程。(实际上once_flag相当于一个锁,使用它的线程都会在上面等待,只有一个线程允许执行。如果该线程抛出异常,那么从等待中的线程中选择一个,重复上面的流程)。
代码实例如下:
#include<iostream>
#include<thread>
#include<mutex>
#include<string>static Log *Log = nullptr; //懒汉模式,需要的时候再去创建一个对象。
static std::once_flag once;class Log {
public:Log() {};Log(const Log& log) = delete;Log& operator = (const Log& log) = delete;/*****************************static Log& GetIntance(){static Log *Log = nullptr; //懒汉模式,需要的时候再去创建一个对象。if(!Log) Log = new Log;return *Log;}****************************/ static Log& GetIntance(){std::call_once(once,init);return *Log; }
};static void init()
{if(!Log) Log = new Log;
}void printfLog(std::string msg){std::cout<<msg<<std::endl;
}void func(std::string msg){Log::GetInstance().printLog("error!!!");
}int main(){std::thread t1(func);std::thread t1(func);t1.json;t2.json;Log::GetInstance().printLog("error!!!");
}
相关文章:
c++单例模式和call_once函数
单例模式是一种常见的设计模式,用于确保某个类只能创建一个实例。由于单例模式是全局唯一的,因此在多线程中使用单例模式时需要考虑线程安全问题。 1.GetInstance()实例化一个对象 懒汉式:第一次用到类的时候才会去实例化。 懒汉式创建对象…...
AutoMQ 携手阿里云共同发布新一代云原生 Kafka,帮助得物有效压缩 85% Kafka 云支出!
3 月 9 日,“AutoMQ x 阿里云云原生创新论坛”在阿里巴巴西溪园区圆满落幕。本次论坛现场不仅重磅发布了新一代云原生 Kafka 产品(AutoMQ On-Prem 版),还邀请了来自得物的稳定生产负责人分享 AutoMQ 在生产场景中的应用实践&…...
力扣977. 有序数组的平方
思路:暴力法:全部平方,然后调用排序API,排序算法最快是N*log(N)时间复制度。 双指针法:要利用好原本的数组本就是有序的数组这个条件, 只是有负数 导致平方后变大了,那么平方后的最大值就是在两…...
VSCode设置
VSCode设置 VSCode设置1.双击和点击显示设置2.快捷键设置 VSCode设置 1.双击和点击显示设置 VSCode设置双击才能打开文件、文件夹 打开文件夹:在设置页中搜索 expandMode,将 singleClick 改为 doubleClick 即可。 双击打开文件:在设置页中搜索workben…...
2.2 评估方法 机器学习
我们若有一个包含m个样例的数据集,若我们既需要训练,也需要测试,我们该如何处理呢?下面是几种方法: 2.2.1 留出法 “留出法”直接将数据集D划分为两个互斥的集合,其中一个作为训练集S,另一个作…...
第一类换元法(凑微分,凑狗)【高数笔记】
1.第一类换元法,解决的是什么类型的问题 2.不同的问题,应该有什么解法 3.13个基本积分公式,应该注意什么...
PostgreSQL数据库优化指南
默认安装下的 PostgreSQL 配置无法完全利用现有硬件,影响Netbox的性能。 本文章讲解了如何简单去优化。 优化 项目地址:https://github.com/le0pard/pgtune 首先打开:https://pgtune.leopard.in.ua/ (此网站会根据你的选择自动生成优化配置…...
VScode Error Lens插件
安装完成之后,当我们输入一些错误的语法格式的时候,它都会有一些提示! 一开始是英文提示 修改为中文提示 设置搜索 typescript.local...
Fiddler抓包教程
一、Fiddler安装: Fiddler原理 B/S模式的工作过程,简单的讲述访问一个网站的过程 。 Fiddler的位置: Fiddler是位于浏览器和服务器之间的请求和响应代理,所以它可以截获浏览器和服务器之间的所有HTTP通讯,࿰…...
TypeScript编译选项
编译单个文件:终端 tsc 文件名 自动编译单个文件:终端 tsc 文件名 -w 编译整个项目:tsc 前提是得有ts的配置文件tsconfig.json 自动编译整个项目:tsc --w tsconfig.json默认文件内容: tsconfig.json是ts编译器的配…...
个推与华为深度合作,成为首批支持兼容HarmonyOS NEXT的服务商
自华为官方宣布HarmonyOS NEXT鸿蒙星河版开放申请以来,越来越多的头部APP宣布启动鸿蒙原生开发,鸿蒙生态也随之进入全新发展的第二阶段。 作为华为鸿蒙生态的重要合作伙伴,个推一直积极参与鸿蒙生态建设。为帮助用户在HarmonyOS NEXT上持续享…...
TypeScript开发100问?
开发人员在日常工作中常常需要处理各种各样的问题,而 TypeScript 作为 JavaScript 的一个超集,为我们提供了更加强大和可靠的工具来编写高质量的代码。在使用 TypeScript 进行开发时,我们可能会遇到各种各样的技术基础问题、开发过程中的挑战…...
数据结构和算法:栈与队列
栈 栈 (stack)是一种遵循先入后出逻辑的线性数据结构 把堆叠元素的顶部称为“栈顶”,底部称为“栈底”。 将把元素添加到栈顶的操作叫作“入栈”,删除栈顶元素的操作叫作“出栈”。 栈的常用操作 /* 初始化栈 */ stack<int&g…...
LeetCode(力扣)算法题_1261_在受污染的二叉树中查找元素
今天是2024年3月12日,可能是因为今天是植树节的原因,今天的每日一题是二叉树🙏🏻 在受污染的二叉树中查找元素 题目描述 给出一个满足下述规则的二叉树: root.val 0 如果 treeNode.val x 且 treeNode.left ! n…...
Topaz DeNoise AI for Mac/Win:引领图片降噪新纪元,让你的照片焕然一新!
在数字化时代,摄影已成为我们记录生活、表达情感的重要方式。然而,随着摄影技术的不断发展,我们也不得不面对一个令人头疼的问题——图片噪点。无论是低光环境下的拍摄,还是高ISO带来的画质损失,噪点总是如影随形&…...
云计算OpenStack KVM迁移
动态迁移 static migration 静态迁移 cold migration 冷迁移 offline migration 离线迁移 live migration 动态迁移 hot migration 热迁移 online migration 在线迁移 衡量 整体迁移时间 服务器停机时间 性能影响(迁移后和其它客户机) 特点 负载均衡 解除硬件依赖…...
【漏洞复现】网康科技 NS-ASG 应用安全网关 SQL注入漏洞(CVE-2024-2330)
免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…...
2024年华为OD机试真题-查找众数及中位数-Java-OD统一考试(C卷)
题目描述: 众数是指一组数据中出现次数量多的那个数,众数可以是多个。 中位数是指把一组数据从小到大排列,最中间的那个数,如果这组数据的个数是奇数,那最中间那个就是中位数,如果这组数据的个数为偶数,那就把中间的两个数之和除以2,所得的结果就是中位数。 查找整型数…...
力扣思路题:重复的子字符串
注意比较j与j-i是否相同 bool repeatedSubstringPattern(char* s) {int i;int nstrlen(s);bool flag;for(int i1;i<n/2;i){if(n%i0){flagtrue;}for(int ji;j<n;j){if(s[j]!s[j-i]){flagfalse;break;}}if(flagtrue){return true;}}return false; }...
同城即配年度观察:顺丰同城率先全年盈利,行业破局迎参考
即时消费趋势增强,“万物到家即时可得”成为了消费新常态。这创造出不可忽视的场景潜力,也在无形中让龙头企业的发展质量走到突破点。 3月11日晚,“第三方即时配送第一股”顺丰同城发布公告称,预期实现2023年全年盈利,…...
Obsidian: 图片管理插件-Local Images Plus与Paste Image Rename的进阶配置指南
1. 为什么需要图片管理插件 如果你经常用Obsidian写笔记,肯定遇到过这样的烦恼:从网页复制粘贴的图片默认存放在系统剪贴板,关闭笔记后图片就消失了;或者随手粘贴的图片文件名杂乱无章,过段时间根本分不清是哪篇笔记的…...
如何快速掌握Unity游戏模组管理:5分钟终极指南
如何快速掌握Unity游戏模组管理:5分钟终极指南 【免费下载链接】unity-mod-manager UnityModManager 项目地址: https://gitcode.com/gh_mirrors/un/unity-mod-manager 还在为Unity游戏模组安装繁琐而烦恼吗?每次想为游戏添加新功能,却…...
RVC实时语音变声实战:YY语音/腾讯会议变声效果亲测
RVC实时语音变声实战:YY语音/腾讯会议变声效果亲测 1. RVC语音变声器简介 RVC(Retrieval-based-Voice-Conversion)是一款开源的AI语音转换工具,它能够实现高质量的实时语音变声效果。不同于传统的变声软件,RVC基于深…...
Pr剪辑效率翻倍秘籍:除了选对GPU加速,这3个隐藏设置让你的老电脑也起飞
Pr剪辑效率翻倍秘籍:除了选对GPU加速,这3个隐藏设置让你的老电脑也起飞 在视频剪辑的世界里,时间就是金钱。当你盯着进度条缓慢爬行,或者面对频繁的卡顿和崩溃时,那种无力感足以让任何创意工作者抓狂。很多人第一时间…...
Flowable UI 6.6.0 生产环境部署踩坑实录:从H2内存库迁移到PostgreSQL的全过程
Flowable UI 6.6.0 生产环境部署实战:从H2到PostgreSQL的完整迁移指南 当你第一次接触Flowable UI时,可能会被它默认的H2内存数据库所迷惑——启动简单,但重启后数据全无。这种配置显然不适合生产环境。本文将带你深入实战,完成从…...
别再只会‘永不在此停止’了!实战绕过网站JS混淆与内存爆破的三种硬核方法
实战突破:三种硬核方法破解JS混淆与内存爆破 打开开发者工具的那一刻,页面突然卡死,控制台不断弹出debugger断点——这可能是每个爬虫工程师都经历过的噩梦。当简单的"永不在此停止"失效时,我们需要更高级的技术手段来应…...
港大新作GS-SDF开源了!手把手教你用激光雷达+3DGS复现IROS2025论文效果(附避坑指南)
港大GS-SDF开源项目实战:从环境配置到效果复现全指南 当激光雷达遇上3D高斯溅射,会碰撞出怎样的火花?港大MARS实验室最新开源的GS-SDF项目给出了令人惊艳的答案。这个将LiDAR点云与神经符号距离场(SDF)相结合的创新方…...
DeepSeek linux-6.19/kernel/events/ring_buffer.c 源码分析
我来分析 Linux 6.19 内核中 kernel/events/ring_buffer.c 的源码。这个文件实现了 perf events 子系统的环形缓冲区管理,用于在内核和用户空间之间高效传递性能事件数据。 文件概述 ring_buffer.c 是 perf events 系统的核心组件,负责管理用于存储性能事…...
在WSL中一键部署Phi-4-mini-reasoning:Windows开发者的Linux模型推理环境搭建
在WSL中一键部署Phi-4-mini-reasoning:Windows开发者的Linux模型推理环境搭建 1. 为什么选择WSL部署Phi-4-mini-reasoning 对于习惯Windows环境的开发者来说,直接在本地运行Linux环境下的AI模型往往是个挑战。Windows Subsystem for Linux (WSL) 提供了…...
告别景深烦恼:用PyTorch+PyQt5打造你的专属多焦点图像融合桌面工具(附完整源码)
告别景深烦恼:用PyTorchPyQt5打造你的专属多焦点图像融合桌面工具 每次拍摄微距或静物时,是否总在景深和清晰度之间纠结?按下快门后才发现前景清晰时背景模糊,背景聚焦时前景又失焦。专业摄影师会告诉你:这是光学镜头的…...
