0

0

C++中如何实现线程安全的单例模式?(双重检查锁定或局部静态变量)

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-01-14 11:49:02

|

443人浏览过

|

来源于php中文网

原创

c++11前双重检查锁定易出问题,主因是编译器/cpu重排序致instance指针提前赋值而对象未构造完,volatile无效且缺乏标准内存模型;c++11起推荐局部静态变量实现,线程安全、异常安全、简洁高效。

c++中如何实现线程安全的单例模式?(双重检查锁定或局部静态变量)

为什么双重检查锁定在C++11之前容易出问题

核心原因是编译器重排序和CPU指令重排可能导致 instance 指针被提前赋值,而对象构造尚未完成。其他线程看到非空指针后直接使用,就会访问未初始化的内存,引发未定义行为。

即使加了 std::mutex,若不配合内存序控制,也无法阻止这种重排。C++11 之前缺乏标准的内存模型支持,volatile 在此场景下完全无效——它既不能禁止重排,也不能提供跨线程同步语义。

  • 老式写法中用 volatile Singleton* instance 是典型误区
  • 没有 std::atomic_thread_fence 或原子操作保障,if (instance == nullptr) 的两次检查之间无同步依据
  • 构造函数抛异常时,instance 可能已置为非空但对象未就绪,后续调用会崩溃

C++11 及以后推荐用局部静态变量(最简且安全)

这是目前最推荐的方式:利用 C++11 标准保证的“函数内局部静态变量的首次初始化是线程安全的”,由编译器自动插入必要的锁和内存屏障,无需手动管理。

它天然规避了双重检查的所有陷阱,代码简洁,性能好(仅首次调用有开销),且支持异常安全(初始化失败时下次仍会重试)。

立即学习C++免费学习笔记(深入)”;

Boba.video
Boba.video

AI动漫视频生成器

下载
class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton instance; // ✅ 线程安全,延迟初始化
        return instance;
    }
<p>private:
Singleton() = default;
~Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
  • 注意:必须是 static Singleton instance;,不是 static Singleton* instance = new Singleton;
  • 该机制依赖编译器实现(如 GCC/Clang/MSVC 均已完整支持),无需额外标志
  • 如果类构造函数可能抛异常,标准规定:每次调用 getInstance() 都会重新尝试初始化,直到成功或程序终止

如果非要手写双重检查锁定,请严格按 C++11+ 规范来

关键点不在“双重检查”,而在原子操作与内存序的精确控制。必须使用 std::atomic 和显式 memory_order,否则仍是错的。

class Singleton {
public:
    static Singleton& getInstance() {
        Singleton* ptr = instance.load(std::memory_order_acquire);
        if (ptr == nullptr) {
            std::lock_guard<std::mutex> lock(mtx);
            ptr = instance.load(std::memory_order_relaxed);
            if (ptr == nullptr) {
                ptr = new Singleton();
                instance.store(ptr, std::memory_order_release);
            }
        }
        return *ptr;
    }
<p>private:
static std::atomic<Singleton*> instance;
static std::mutex mtx;</p><pre class='brush:php;toolbar:false;'>Singleton() = default;
~Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;

};

std::atomic Singleton::instance{nullptr}; std::mutex Singleton::mtx;

  • instance 必须是 std::atomic<singleton></singleton>,不能是裸指针 + volatile
  • 首次读用 memory_order_acquire,写用 memory_order_release,确保构造完成对其他线程可见
  • 内部第二次读可用 memory_order_relaxed,因已持锁,无需额外同步
  • 仍需注意:析构无法自动管理;若需销毁逻辑,得额外设计(如 atexit 或手动清理)

局部静态变量方式的隐藏限制你可能忽略

它虽简单可靠,但有两个实际约束常被忽视:

  • 无法控制销毁时机:对象在 main() 返回后、全局对象析构阶段被销毁,若其他静态对象的析构函数中调用 getInstance(),可能触发二次初始化或访问已销毁对象
  • 不适用于需要自定义内存分配(如 placement new)或跨 DLL 边界的场景:各模块可能拥有独立的局部静态变量实例
  • 若单例依赖其他尚未初始化的静态对象(比如某全局日志器),构造顺序不可控,可能 crash

遇到这些情况,才值得考虑带控制权的双重检查实现,但务必用原子操作,别碰 volatile 或手写汇编屏障。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

846

2023.08.22

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

75

2025.10.23

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

763

2023.08.10

空指针异常处理
空指针异常处理

本专题整合了空指针异常解决方法,阅读专题下面的文章了解更多详细内容。

23

2025.11.16

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

28

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

68

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

164

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

84

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

114

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号