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

一:概述:

在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. 无锁实现:在实现细节上,现代标准库可能会使用无锁算法,减少锁竞争的开销。

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

cpp 复制代码
#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'; // 输出空行,美化输出
}
相关推荐
Tanecious.11 分钟前
C++--红黑树
开发语言·c++
Top`15 分钟前
Java 泛型 (Generics)
java·开发语言·windows
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ40 分钟前
如何使用Java WebSocket API实现客户端和服务器端的通信?
java·开发语言·websocket
Shartin1 小时前
Can201-Introduction to Networking: Application Layer应用层
服务器·开发语言·php
共享家95271 小时前
linux_线程概念
linux·开发语言·jvm
apihz2 小时前
VM虚拟机全版本网盘+免费本地网络穿透端口映射实时同步动态家庭IP教程
android·服务器·开发语言·网络·数据库·网络协议·tcp/ip
tanyongxi663 小时前
C++ Map 和 Set 详解:从原理到实战应用
开发语言·c++
飒飒真编程3 小时前
C++类模板继承部分知识及测试代码
开发语言·c++·算法
博睿谷IT99_4 小时前
华为数据通信网络基础
开发语言·华为·php·华为认证
蓝桉(努力版)4 小时前
MATLAB可视化5:华夫图(饼图的平替可以表示种类的分布,附有完整代码详细讲解)(求个关注、点赞和收藏)(对配色不满意可以自己调节配色,附调色教程)
开发语言·数学建模·matlab·信息可视化·matlab可视化