C++ 并发专题 - 线程安全的单例模式

news/2024/11/23 16:41:27/

一:概述:

        在C++编程中,call_once 是一种机制,用于确保某个函数或代码段在多线程环境下仅被调用一次。这种机制常用于初始化资源、配置全局变量或执行只需执行一次的逻辑。在 C++11 标准中,std::call_once 是由标准库提供的工具,它与 std::once_flag 配合使用,能够实现线程安全的一次性初始化。

二:工作原理:

  1. std::once_flag:是一个标志,标识某段代码是否已经被调用过。
  2. std::call_once:接收一个 std::once_flag 和一个函数/可调用对象,只在第一次调用时执行,后续调用直接返回

三:特点和优点

  1. 线程安全:即使多个线程同时调用,std::call_once 也保证函数只执行一次。
  2. 性能优化:相比手写的双重检查锁机制,std::call_once 更简洁、易用且高效。
  3. 无锁实现:在实现细节上,现代标准库可能会使用无锁算法,减少锁竞争的开销。

四:例子(线程安全的单例模式)

#include <iostream>
#include <mutex>// 单例类 MySingleton
class MySingleton {private:static std::once_flag initInstanceFlag; // 标志位,确保初始化函数只调用一次static MySingleton * instance;         // 指向单例实例的静态指针// 私有化构造函数和析构函数,防止外部创建或销毁实例MySingleton() = default;~MySingleton() = default;public:// 删除拷贝构造函数和赋值运算符,防止复制或赋值单例对象MySingleton(const MySingleton&) = delete;MySingleton& operator = (const MySingleton&) = delete;// 获取单例实例的方法static MySingleton * getInstance() {// 使用 std::call_once 确保 initSingleton 只被调用一次std::call_once(initInstanceFlag, MySingleton::initSingleton);return instance;}// 初始化单例实例的静态方法static void initSingleton() {instance = new MySingleton();}
};// 定义静态成员变量,初始化为空
MySingleton * MySingleton::instance = nullptr;
std::once_flag MySingleton::initInstanceFlag;int main() {// 输出空行,仅用于美化输出std::cout << '\n';// 第一次调用 getInstance 时,初始化单例对象std::cout << "MySingleton::getInstance(): " << MySingleton::getInstance() << '\n';// 第二次调用 getInstance,不会重新初始化,返回同一个实例std::cout << "MySingleton::getInstance(): " << MySingleton::getInstance() << '\n';std::cout << '\n'; // 输出空行,美化输出
}


http://www.ppmy.cn/news/1549326.html

相关文章

Java SE 与 Java EE:基础与进阶的探索之旅

在编程世界中&#xff0c;Java语言以其跨平台、面向对象、丰富的类库等特点&#xff0c;成为了众多开发者和企业的首选编程语言。而Java SE与Java EE&#xff0c;作为Java平台的两个重要组成部分&#xff0c;各自承载着不同的使命&#xff0c;同时又紧密相连&#xff0c;共同构…

Elasticsearch客户端在和集群连接时,如何选择特定的节点执行请求的?

大家好&#xff0c;我是锋哥。今天分享关于【Elasticsearch客户端在和集群连接时&#xff0c;如何选择特定的节点执行请求的&#xff1f;】面试题。希望对大家有帮助&#xff1b; Elasticsearch客户端在和集群连接时&#xff0c;如何选择特定的节点执行请求的&#xff1f; 100…

前端知识点---rest(javascript)

文章目录 前端知识点---rest(javascript)rest的用法基本语法特点使用场景与扩展运算符&#xff08;spread&#xff09;区别小练习 前端知识点—rest(javascript) rest出现于ES2015 function doSum(a,b, ...args) //示例中的args就是一个rest参数 //它会将后续的所有参数存储…

AI技术在电商行业中的应用面临哪些挑战?

AI技术在电商行业的应用尽管具有巨大潜力&#xff0c;但也面临以下主要挑战&#xff1a; 挑战 1. 数据质量与隐私问题 数据量与质量不均&#xff1a;电商平台需要大量高质量数据来训练AI模型&#xff0c;但数据可能不完整、不准确&#xff0c;或存在偏差&#xff0c;影响AI预…

概率论和数理统计知识点汇总——第二章随机变量的分布与数字特征

2.1 随机变量及其分布 1.随机变量的概念 定义2.1 定义在概率空间(Ω,P)上,取值为实数的函数xx(ω)(w∈Ω)称为(Ω,P)上的一个随机变量.) 基本事件:Xa 复合事件:X 2.离散型随机变量的概率分布 定义&#xff1a;X的全部可能取值只有有限个或可数无穷多个 性质&#xff1a; 3…

shell编程(8) until循环以及函数基本创建调用

声明!!! 学习视频来自B站UP主泷羽sec&#xff0c;如涉及侵权马上删除文章 视频链接&#xff1a;泷羽sec 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 # until循环 脚本代码&#xff1a; i0 until [ ! $i -lt 1…

Hello-Go

Hello-Go 环境变量 GOPATH 和 GOROOT &#xff1a;不同于其他语言&#xff0c;go中没有项目的说法&#xff0c;只有包&#xff0c;其中有两个重要的路径&#xff0c;GOROOT 和 GOPATH Go开发相关的环境变量如下&#xff1a; GOROOT&#xff1a;GOROOT就是Go的安装目录&…

鸿蒙安全控件之粘贴控件简介

粘贴控件是一种特殊的系统安全控件&#xff0c;它允许应用在用户的授权下无提示地读取剪贴板数据。 在应用集成粘贴控件后&#xff0c;用户点击该控件&#xff0c;应用读取剪贴板数据时不会弹窗提示。可以用于任何应用需要读取剪贴板的场景&#xff0c;避免弹窗提示对用户造成…