【线程安全的单例模式和STL是否是线程安全/智能指针是否是线程安全】

文章目录

  • 一、单例模式的特点
  • 二、饿汉模式实现单例
  • 三、懒汉模式实现单例
  • 四、STL线程安全吗?
  • 五、智能指针线程安全吗?


一、单例模式的特点

一个类,只应该实例化了一个对象,就是单例。

二、饿汉模式实现单例

举个饿汉模式的例子:洗碗,一个人吃碗饭之后,他马上洗碗,下次吃饭的时候就可以直接拿起碗吃饭了。这就是饿汉模式。
懒汉模式是:一个人吃完饭之后,他先不洗碗,下次吃饭的时候再洗碗,这就是懒汉模式。
懒汉模式的核心特点是:延迟加载。

饿汉模式实现单例:
template<class T>
class Singleton
{
private:static T inst;public:static T* GetInstance(){return &inst;}
};

通过SingleTon类实例化的对象只能拥有一个。

三、懒汉模式实现单例

懒汉模式具体是什么已经介绍过了。
下面用代码实现懒汉模式

懒汉模式实现单例
template<class T>
class Singleton
{
private:static T* inst;public:static T* GetInstance(){if(inst == nullptr)inst  = new T();return inst;}
};

但是这样的懒汉模式存在线程安全,假如有两个线程同时进入GetInstance函数中new T()呢?
这样就会存在两个inst指针指向的对象了, 就不再是单例了。

所以需要加锁保证线程安全。
下面是线程安全版本的单例模式

template <class T>
class Singleton
{
private:static std::mutex lock;volatile static T* inst;  //设置volatile关键字的目的是防止被编译器优化
public:static T* GetInstance(){lock.lock();if(inst == nullptr)		//判断的本质也是再访问临界资源,所以要在加锁之后inst = new T();lock.unlock();return inst;}

这样解决了线程并发问题,但是这样假如有大量线程同时进入该函数时,会并发竞争锁,会造成性能低下,极端情况下可能出现卡顿现象。
因为不管有没有实例化T对象,都会进行锁竞争,这是不太合理的。

正确的应该是:如果没有实例化T对象,先申请锁对T对象new一个出来。
如果有了T对象,直接返回即可。
下面是改正后的代码:

template <class T>
class Singleton
{
private:static std::mutex lock;volatile static T* inst;  //设置volatile关键字的目的是防止被编译器优化
public:static T* GetInstance(){if(inst == nullptr)   //双重判定空指针, 降低锁冲突的概率, 提高性能{lock.lock();if(inst == nullptr)   //判断的本质也是再访问临界资源,所以要在加锁之后inst = new T();lock.unlock();}return inst;}};

这样实现懒汉模式的单例模式,解决了线程安全+性能低下的问题。

四、STL线程安全吗?

不是
原因是, STL 的设计初衷是将性能挖掘到极致, 而一旦涉及到加锁保证线程安全, 会对性能造成巨大的影响.而且对于不同的容器, 加锁方式的不同, 性能可能也不同(例如hash表的锁表和锁桶).
因此 STL 默认不是线程安全. 如果需要在多线程环境下使用, 往往需要调用者自行保证线程安全

五、智能指针线程安全吗?

对于 unique_ptr, 由于只是在当前代码块范围内生效, 因此不涉及线程安全问题
对于 shared_ptr, 多个对象需要共用一个引用计数变量, 所以会存在线程安全问题.但是标准库实现的时候考虑到了这个问题, 基于原子操作(CAS)的方式保证 shared_ptr 能够高效, 原子的操作引用计数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39550.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++KNN 算法应用痛点:从受噪声干扰到精准预测的突破

在机器学习算法家族中,K近邻(K-Nearest Neighbors,KNN)算法以其概念简单却又异常强大的特性脱颖而出。作为一名长期从事高性能计算优化的C++专家,我始终对KNN算法情有独钟。为何如此?想象一下,在数十种复杂的算法中,有一种算法能够不需要繁琐的数学推导,仅凭直觉就能理…

996引擎-接口测试:消息Tips

996引擎-接口测试:消息Tips 发送视野内广播消息 sendrefluamsg发送聊天框消息 sendmsg发送地图消息 sendmapmsg打印消息到控制台 release_print发送自定义颜色的文字信息 guildnoticemsg测试NPC参考资料发送视野内广播消息 sendrefluamsg function npc_test_onclick1(player)-…

2025年上软考——【系统架构设计师】考前60天冲刺学习指南!!!

距离2025上半年“系统架构设计师”考试已经只剩两个月了&#xff0c;还没有开始备考的小伙伴赶紧行动起来。为了帮助大家更好的冲刺学习&#xff0c;特此提供一份考前60天学习指南。本指南包括考情分析、学习规划、冲刺攻略三个部分&#xff0c;可以参考此指南进行最后的复习要…

Redis 服务搭建

&#x1f4a2;欢迎来到张翊尘的开源技术站 &#x1f4a5;开源如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Redis 服务搭建源代码编译安装获取源码安装依赖Ub…

【AI神经网络】深度神经网络(DNN)技术解析:从原理到实践

引言 深度神经网络&#xff08;Deep Neural Network, DNN&#xff09;作为人工智能领域的核心技术&#xff0c;近年来在计算机视觉、自然语言处理、医疗诊断等领域取得了突破性进展。与传统机器学习模型相比&#xff0c;DNN通过多层非线性变换自动提取数据特征&#xff0c;解决…

FPGA中串行执行方式之流水线(Pipeline)

FPGA中串行执行方式之流水线(Pipeline) 在FPGA设计中,​流水线(Pipeline)​ 是一种常见的优化技术,用于提高系统的吞吐量和性能。流水线通过将复杂的逻辑分解为多个阶段,每个阶段在一个时钟周期内完成一部分工作,并将中间结果传递到下一阶段。这种方式可以显著提高时钟…

【机器学习】什么是决策树?

什么是决策树&#xff1f; 决策树是一种用于分类和回归问题的模型。它通过一系列的“决策”将数据逐步分裂&#xff0c;最终得出预测结果。可以把它看作是一个“树”&#xff0c;每个节点表示一个特征的判断&#xff0c;而每个分支代表了可能的判断结果&#xff0c;最终的叶子…

ZW3D二次开发_非模板表单_控件_添加回调

ZW3D的非模板表单的控件即“ZW3D Widgets”下的控件&#xff0c;常用的如“ZsCc::ComboBox”,"Zscc::ListWidget","ZsCc::MatrixPushButtons","Zscc::TableWidget"和"ZsCc::TreeView"等&#xff0c;使用它们时&#xff0c;ZW3D在内部实…

git 合并多次提交 commit

在工作中&#xff0c;有时候在反复修改代码中&#xff08;比如处理MR的检视意见&#xff0c;或者为了推送到测试环境&#xff0c;先 commit到自己的远程分支上&#xff09;不免会有多次 commit&#xff0c;这样发起 MR 的时候&#xff0c;就会有一堆 commit 信息&#xff0c;看…

【golang学习之旅】使用VScode安装配置Go开发环境

1. 下载并安装Go 1.1 下载地址1.2 选择版本并下载1.3 安装目录1.4 验证是否安装成功 2. 配置环境变量 2.1 配置步骤2.2 GO部分环境变量说明 3. 下载或更新 Vscode 3.1 下载地址3.2 安装步骤 4. 为Go开发配置VScode 1. 下载并安装Go 1.1 下载地址 https://studygolang.com/dl…

制作PaddleOCR/PaddleHub的Docker镜像

背景 在落地RAG知识库过程中&#xff0c;遇到了图文识别、图片表格内容识别的需求。但那时&#xff08;2024年4月&#xff09;各开源RAG项目还没有集成成熟的解决方案&#xff0c;经调研我选择了百度开源的PaddleOCR。支持国产&#xff01; 概念梳理 PaddleOCR 百度飞桨的OCR…

Mysql基本查询(上)

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 1. 创建&#xff08;create&#xff09; 全列插入 省略into插入 插入…

[工控机安全] 使用DriverView快速排查不可信第三方驱动(附详细图文教程)

导语&#xff1a; 在工业控制领域&#xff0c;设备驱动程序的安全性至关重要。第三方驱动可能存在兼容性问题、安全漏洞甚至恶意代码&#xff0c;威胁设备稳定运行。本文将手把手教你使用 DriverView工具&#xff0c;高效完成工控机驱动安全检查&#xff0c;精准识别可疑驱动&a…

Docker 镜像构建与优化

一、Dockerfile 构建镜像 1.1.拉取所需镜像 首先 docker pull 拉取一个 centos7 的镜像。 docker pull centos:7 下载 nginx 源码包。 官网&#xff1a;nginx: download wget https://nginx.org/download/nginx-1.26.3.tar.gz 1.2.解决 CentOS 7 安装源问题 因为原本的 …

PHP回调后门分析

什么是PHP回调后门&#xff1f; PHP回调后门是指攻击者利用PHP的回调函数等技术&#xff0c;绕过WAF&#xff08;Web应用防火墙&#xff09;&#xff0c;在受攻击的PHP应用程序中插入恶意代码。这种后门可以被用来执行任意PHP代码&#xff0c;例如访问数据库、执行系统命令、窃…

vue数据重置

前言 大家在开发后台管理系统的过程中&#xff0c;一定会遇到一个表格的条件查询重置功能吧&#xff0c;如果说查询条件少&#xff0c;重置起来还算是比较简单&#xff0c;如果元素特别多呢&#xff0c;那玩意写起来可遭老罪喽&#xff0c;那今天就给大家整一个如何快速重置数…

【js逆向入门】图灵爬虫练习平台 第九题

地址&#xff1a;aHR0cHM6Ly9zdHUudHVsaW5ncHl0b24uY24vcHJvYmxlbS1kZXRhaWwvOS8 f12进入了debugger&#xff0c;右击选择一律不在此处暂停&#xff0c; 点击继续执行 查看请求信息 查看载荷&#xff0c;2个加密参数&#xff0c;m和tt 查看启动器&#xff0c;打上断点 进来 往…

OpenCV第2课 OpenCV的组成结构与图片/视频的加载及展示

1.OpenCV 的组成结构 2.OpenCV 的具体模块 3. 图像的读取 4. 视频的读取 1.OpenCV 的组成结构 OpenCV 是由很多模块组成的,这些模块可以分成很多层: 最底层是基于硬件加速层(HAL)的各种硬件优化。再上一层是opencv_contrib 模块所包含的OpenCV 由其他开发人员所贡献的代…

scNET:整合scRNA-seq和PPI用于学习基因和细胞的embedding

scRNA-seq 技术的最新进展为深入了解各种组织的异质性提供了前所未有的视角。然而&#xff0c;仅靠基因表达数据往往无法捕捉和识别细胞通路和复合物的变化&#xff0c;因为这些变化在蛋白质水平上更容易被察觉。此外&#xff0c;由于scRNA-seq数据存在高噪声水平和零膨胀等固有…

吴恩达机器学习笔记复盘(十一)逻辑回归的代价和损失函数

简介 逻辑回归是一种二分类算法&#xff0c;损失函数和代价函数和线性回归模型不同。目标是根据特征预测标签Y&#xff08;0或1&#xff09;。模型通过参数W和B拟合数据&#xff0c;但如何选择最优参数成为关键。本质上说线性回归的损失函数是对数值本身的误差平均值描述&…