新闻中心
C++单例模式实现方法_C++线程安全的单例模式写法与DCLP探讨
单例模式确保类仅一个实例并提供全局访问,C++中推荐使用局部静态变量实现线程安全单例,因C++11保证其初始化线程安全、简洁高效;双重检查锁定模式虽性能优但易错,需原子操作与内存序控制,复杂不推荐。

单例模式确保一个类只有一个实例,并提供全局访问点。在C++中,实现线程安全的单例模式需要考虑多线程环境下的初始化竞争问题。最经典且高效的方式是使用“延迟初始化 + 局部静态变量”或“双重检查锁定模式(DCLP)”,但两者有重要区别。
局部静态变量实现(推荐方式)
C++11 起,局部静态变量的初始化具有线程安全性,由编译器保证。这是目前最简洁、安全且高效的单例写法:代码示例:
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // 线程安全,C++11标准保证
return instance;
}
<pre class='brush:php;toolbar:false;'>Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;private: Singleton() = default; ~Singleton() = default; }; 优点:简洁、无需手动加锁、自动析构、线程安全。强烈推荐用于现代C++项目。
双重检查锁定模式(DCLP)详解
在C++11之前,DCLP常用于避免每次调用都加锁。但由于内存可见性和指令重排问题,原始DCLP存在缺陷。错误示例(非线程安全):
Motiff妙多
Motiff妙多是一款AI驱动的界面设计工具,定位为“AI时代设计工具”
334
查看详情
class SingletonBad {
static SingletonBad* instance;
static std::mutex mtx;
<p>public:
static SingletonBad* getInstance() {
if (instance == nullptr) { // 第一次检查
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) { // 第二次检查
instance = new SingletonBad;
}
}
return instance;
}
};
问题:new操作包含三步——分配内存、构造对象、赋值指针。编译器或CPU可能重排序,导致其他线程拿到未完全构造的实例。正确的DCLP写法(使用原子操作和内存屏障)
通过std::atomic和memory_order确保顺序正确:#include <atomic> #include<mutex> <p>class SingletonDCLP { static std::atomic<SingletonDCLP*> instance; static std::mutex mtx;</p><p>public: static SingletonDCLP<em> getInstance() { SingletonDCLP</em> tmp = instance.load(std::memory_order_relaxed); if (tmp == nullptr) { std::lock_guard<std::mutex> lock(mtx); tmp = instance.load(std::memory_order_relaxed); if (tmp == nullptr) { tmp = new SingletonDCLP(); instance.store(tmp, std::memory_order_release); } } return tmp; }</p><pre class='brush:php;toolbar:false;'>SingletonDCLP(const SingletonDCLP&) = delete; SingletonDCLP& operator=(const SingletonDCLP&) = delete;
private:
SingletonDCLP() = default;
};
// 静态成员定义
std::atomic
总结与建议
虽然DCLP理论上有性能优势,但在现代C++中,局部静态变量方式更优:- 代码更简洁,不易出错
- C++11标准明确保证线程安全
- 编译器通常使用类似DCLP的优化机制
- 自动管理生命周期,无需手动释放
基本上就这些。
以上就是C++单例模式实现方法_C++线程安全的单例模式写法与DCLP探讨的详细内容,更多请关注其它相关文章!
# 相关文章
# 中高端水怎么推广营销
# 绍兴海外网站推广平台
# SEO效果跟踪数据
# 成都抖音营销推广代理
# 老年产品营销推广
# 漯河网站建设方案
# 南康区同城网站优化公司
# 东营网站建设那家好
# 芝罘区关键词seo优化
# 新疆旅游推广营销模式分析
# 中文网
# 线程安全
# 上有
# 推荐使用
# 但在
# 这是
# 加锁
# 如何使用
# 尼克
# 多线程
# 区别
# c++
# c++单例模式
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
J*a递归快速排序中静态变量导致数据累积的陷阱与解决方案
PDF文件体积过大处理_PDF压缩技巧详解
极兔快递快件信息查询系统 极兔快递官网运单号追踪
Excel如何用迷你图显趋势_Excel用迷你图显趋势【趋势小图】
J*aScriptWebpack优化_J*aScript构建工具实战
快手赚钱渠道_快手收益来源
Spyder启动失败:字体文件权限拒绝错误解决方案
J*a里如何使用forEach遍历Map_Map遍历方法说明
微信网页版登录教程_微信网页版登录入口在哪
Yandex官方入口网址 Yandex俄罗斯搜索引擎最新在线地址
韩剧圈正版入口页面_韩剧圈官网登录链接
AWS EC2实例间SQL Server连接超时:安全组配置与故障排除指南
Win11蓝牙耳机断连怎么解决 Win11蓝牙设置重新配对与驱动更新【技巧】
蛙漫画网页版全站入口 蛙漫热门作品免费浏览
大麦的“候补”是什么意思 大麦候补购票规则【详解】
c++中的std::forward_list和std::list有什么不同_c++ forward_list与list区别分析
sublime如何配置Go语言开发环境_sublime搭建Golang编译运行系统
PostgreSQL海量数据高效导入策略:Python与Django实践指南
AO3网页版合集入口 Archive of Our Own同人作品浏览指南
J*aScript数据结构转换:将对象数组按类别分组
Win11怎么关闭快速启动_Win11彻底关机设置教程
解决Python logging 中 datefmt 导致时间戳固定不变的问题
C++ typeid如何获取类型信息_C++ RTTI运行时类型识别用法
顺丰快递查单号物流信息 顺丰快递小程序查询入口
Python多线程中正确使用sigwait处理SIGALRM信号
海棠账号登录入口_登录海棠账户同步阅读记录
顺丰快递查询系统 官方正版查询入口
智慧团建扫码登录入口 智慧团建扫码登录入口官网版
J*a 递归快速排序中静态变量的状态管理与陷阱
C#使用XPath查询节点时出错? 常见语法错误与调试技巧
精准捕获:如何在页面中监听除特定元素外的所有点击事件
Golang如何实现简单的Web表单_Golang表单提交与验证处理方法
如何解决电商平台定制报价请求的“黑洞”问题,SprykerQuoteRequest模块助你提升客户体验与销售效率
双系统安装时,如何设置默认启动系统? msconfig命令了解一下!
QQ邮箱稳定登录入口_QQ邮箱官方网站网页版使用
12306几点到几点不能订票? | 官方最新系统维护时间全解析
知乎APP怎么管理已购盐选内容_知乎APP盐选内容购买记录与查看方法
KFC早餐时段怎么领特惠代码_KFC早餐订餐优惠代码获取与使用说明
wps文字怎么插入目录并自动更新_wps文字如何插入目录并自动更新方法
Win10桌面图标出现小盾牌怎么办 Win10去除UAC图标教程【解决】
Golang切片为何属于引用类型_Golang slice底层结构与引用语义说明
必由学官网首页入口 必由学教师网页版登录指南
C++如何操作注册表_Windows平台下C++读写注册表的API函数详解
Win11输入法不见了怎么办_Windows11恢复语言栏显示方法
从OpenAI API响应中高效提取生成文本
J*aScript DOM操作:高效清空列表元素的策略与实践
蛙漫移动版在线看 蛙漫手机浏览器直达入口
现代化 SciPy 一维插值:interp1d 的替代方案与最佳实践
优化Django表单:提交验证失败后保留用户输入
《铁拳8》黑皮辣妹新实机:元气满满的18岁少女!


2025-11-27
浏览次数:次
返回列表
<mutex>
<p>class SingletonDCLP {
static std::atomic<SingletonDCLP*> instance;
static std::mutex mtx;</p><p>public:
static SingletonDCLP<em> getInstance() {
SingletonDCLP</em> tmp = instance.load(std::memory_order_relaxed);
if (tmp == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
tmp = instance.load(std::memory_order_relaxed);
if (tmp == nullptr) {
tmp = new SingletonDCLP();
instance.store(tmp, std::memory_order_release);
}
}
return tmp;
}</p><pre class='brush:php;toolbar:false;'>SingletonDCLP(const SingletonDCLP&) = delete;
SingletonDCLP& operator=(const SingletonDCLP&) = delete;