当前位置: 首页 > news >正文

设计模式-单例设计模式

单例模式的设计和线程安全

单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。实现单例模式时,线程安全性是一个重要考虑因素,特别是在多线程环境中。

1. C++11 之前的线程安全实现

在 C++11 之前,确保单例模式的线程安全通常需要使用互斥锁或双重检查锁定(double-checked locking)技术。以下是这些方法的简要说明:

  • 互斥锁:通过使用 std::mutex 或类似的机制来锁定创建实例的代码区域。这样可以确保在多线程环境中,只有一个线程能够执行实例的创建代码,从而避免多个实例的创建。示例如下:

    class Singleton {
    public:static Singleton& getInstance() {if (!instance) {std::lock_guard<std::mutex> guard(mutex); // 加锁if (!instance) {instance = new Singleton();}}return *instance;}private:Singleton() {}static Singleton* instance;static std::mutex mutex;
    };
    

    这个方法避免了多个线程同时创建多个实例的问题,但锁定可能导致性能瓶颈。

  • 双重检查锁定:这种技术用于减少锁的开销。只有在实例尚未创建时才加锁,实例已经创建后则跳过加锁。示例如下:

    class Singleton {
    public:static Singleton& getInstance() {if (!instance) {std::lock_guard<std::mutex> guard(mutex); // 加锁if (!instance) {instance = new Singleton();}}return *instance;}private:Singleton() {}static Singleton* instance;static std::mutex mutex;
    };
    

    这种方法的实现复杂且容易出错,因为在 C++03 及以前版本中,线程对静态变量初始化的行为未被明确规定,可能会导致不一致的结果。

2. C++11 及其之后的改进

C++11 引入了对局部静态变量初始化的线程安全支持,这简化了单例模式的实现。关键改进包括:

  • 线程安全的局部静态变量初始化

    • C++11 标准保证了局部静态变量的初始化是线程安全的。这意味着,即使多个线程同时调用返回静态局部变量的函数,编译器也会确保该静态变量只被初始化一次,并且线程安全。
    • 这消除了对显式锁定的需求,使得单例模式的实现更简单和高效。

    示例代码:

    class Singleton {
    public:static Singleton& getInstance() {static Singleton instance; // 局部静态变量,线程安全return instance;}private:Singleton() {}
    };
    

    在这个实现中,instance 是一个局部静态变量。C++11 确保当多个线程同时访问 getInstance 方法时,只有一个线程会创建 instance 实例,而其他线程将看到已经初始化的实例。

  • 初始化顺序保证

    • C++11 还保证了局部静态变量的初始化顺序是确定的,即先初始化局部静态变量后才执行其他代码。这确保了静态变量不会在使用前被销毁。
3. 总结
  • C++11 改进:引入了线程安全的局部静态变量初始化机制,简化了单例模式的实现,不再需要手动处理线程安全问题。
  • C++11 之前:需要使用互斥锁或双重检查锁定来确保线程安全,这些方法复杂且容易出错。

C++11 的这些改进显著提升了单例模式的实现简洁性和安全性,使得在多线程环境中使用单例模式变得更加可靠和高效。

http://www.lryc.cn/news/418616.html

相关文章:

  • 23_windows 使用sqlmap、kali使用sqlmap,SQL注入、sqlmap自动注入
  • WPF学习(12)-Image图像控件+GroupBox标题容器控件
  • 【Linux】基础IO认知
  • 7. Kubernetes核心资源之Service服务实战
  • 《向量数据库指南》——企业采用非结构化数据的场景及其深远影响
  • Linux内核编程(十二)热插拔
  • 七夕警示:探索社工库与网络搜索下的个人隐私泄露与保护策略
  • Redis-哨兵监控(sentinel)
  • RISC-V反汇编调试记录分享
  • python上下文管理器 with的使用
  • 24/8/8算法笔记 决策树构建鸢尾花
  • 数据库扩展新篇章:主流分库分表中间件全解析
  • python看图片猜价格游戏,frame 和PhotoImage的使用
  • 未来展望:等保测评在网络安全领域的持续创新与发展
  • 构建深度学习驱动的多目标检测系统:YOLO模型及应用
  • 算法刷题笔记 染色法判定二分图(染色法例题 C++实现)
  • 在Ubuntu上安装OpenBLAS和Eigen
  • Vue前端面试基础(一)
  • 使用Gitlab实现monorepo多项目CICD
  • 设计模式实战:银行账户管理系统的设计与实现
  • ⭕️【论文阅读】《Interactive Class-Agnostic Object Counting》
  • 高效的编程学习方法和技巧
  • sublime text插件开发
  • 【Linux网络】网络层协议:IP
  • 分布式接口文档聚合,Solon 是怎么做的?
  • 多尺度病理图像纹理特征作为肺腺癌预后预测的新指标|文献精读·24-08-09
  • RAG+Agent项目实践系列:基于本地菜谱知识库的大语言模型RAG+Agent的解决方案设计和实现
  • JupyterNotebook添加Anaconda中已有的虚拟环境
  • 利用vscode-icons-js在Vue3项目中实现文件图标展示
  • 某赛通电子文档安全管理系统 CDGAuthoriseTempletService1 SQL注入漏洞复现(XVE-2024-19611)