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年全年盈利,…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
