【C++11 之单例模式线程安全原理+案例】及旧版本互斥锁线程安全案例

在C++11及之后的版本中,当函数返回局部静态变量时,该变量的初始化是线程安全的。

浅层原理

这是因为C++11标准引入了“魔术静态局部变量”(Magic Static Locals)的概念,它确保了在多线程环境中,局部静态变量的初始化只会被执行一次,并且这个初始化过程是线程安全的。

在单例模式中,通常会看到一个私有的静态成员变量和一个公有的静态成员函数get_instance()来返回这个私有静态成员变量的引用或指针。在C++11之前,这种懒汉式单例实现通常需要使用互斥锁(如pthread_mutex_t或std::mutex)来确保线程安全。但在C++11及之后,你可以简单地通过返回一个局部静态变量的引用来实现线程安全的单例。

深层原理

在C++11中,编译器和运行时库合作来确保局部静态对象的线程安全初始化,但是具体的实现细节是依赖于编译器和平台的。不过,从概念上讲,我们可以大致理解编译器是如何判断“第一次”和“后续次”调用的。

  1. 编译时标记:编译器在编译时识别出函数中的静态局部对象,并标记这个对象需要特殊的初始化处理。这个标记可能是一个标志,指示运行时库在第一次调用该函数时进行初始化。
  2. 运行时检查:当函数被调用时,运行时库会检查该静态局部对象是否已经被初始化。这通常是通过检查一个与静态局部对象相关联的标志位来实现的。这个标志位可能在静态对象的内存区域附近或者在某个专门的区域中。
  3. 初始化锁:如果运行时库发现静态对象尚未初始化,它会使用一个锁(例如互斥锁)来确保只有一个线程可以执行初始化代码。这个锁保证了同一时间只有一个线程可以访问初始化代码段。
  4. 执行初始化:获得锁的线程将执行静态对象的初始化代码。这可能包括调用构造函数、分配内存等。
  5. 设置已初始化标志:一旦初始化完成,运行时库将设置与静态对象相关联的标志位,表示该对象已经初始化。
  6. 后续调用:当其他线程调用该函数时,运行时库会检查已初始化标志。由于这个标志已经设置,运行时库知道静态对象已经初始化,因此它不会再次执行初始化代码,而是直接返回对象的引用或指针。
  7. 锁的释放:获得锁的线程在初始化完成后会释放锁,允许其他线程继续执行。

此外,C++标准并没有规定具体的实现细节,所以不同的编译器和平台可能会有不同的实现方式。但是,它们都必须遵守C++11标准对线程安全初始化的要求。

以下是一个C++11线程安全单例模式的简单示例:

class Singleton {
   
     
public:  
    static Singleton& get_instance() {
   
     
        static Singleton instance; // C++11中局部静态变量初始化是线程安全的  
        return instance
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flos chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值