首页 > 编程语言 >为什么C++ 单例局部static初始化是线程安全的?

为什么C++ 单例局部static初始化是线程安全的?

时间:2024-01-14 19:34:36浏览次数:34  
标签:AppSettings C++ 实例 线程 构造 单例 static constructed

为什么C++ 单例局部static初始化是线程安全的?

const bg::AppSettings& bg::AppSettings::GetInstance()
{
    static AppSettings instance;
    return instance;
}

对于以上单例模式代码,在 C++11(及更高版本)中,函数局部静态AppSettings的构造保证是线程安全的。

编译器将在 AppSettings 旁边放置一个隐藏标志,指示它是否:

  • Not constructed.
  • Being constructed.
  • Is constructed.

第一个线程将发现标志设置为“Not constructed”并尝试构造该对象。成功构建后,标志将设置为“Is constructed”。如果另一个线程出现并发现标志设置为“Being constructed”,它将等待,直到标志设置为“Is constructed”。

如果构造因异常而失败,则标志将设置为“Not constructed”,并且将在下一次传递时重试构造(在同一线程或不同线程上)。

对象实例将在程序的其余部分中保持构造状态,直到main() 返回,此时实例将被销毁。

每次任何执行线程通过 AppSettings::GetInstance() 时,它将引用完全相同的对象。

在 C++98/03 中,不保证构造是线程安全的。

如果 AppSettings 的构造函数递归地进入 AppSettings::GetInstance(),则行为未定义。

如果编译器可以“在编译时”了解如何构造实例,则允许这样做。

如果 AppSettings 有一个 constexpr 构造函数(用于构造实例的构造函数),并且该实例是用 constexpr 限定的,则编译器需要在编译时构造实例。如果实例是在编译时构造的,则“未构造/构造”标志将被优化掉。

参考

[1]C++11 Singleton. Static variable is thread safe? Why?

[2]Is Meyers' implementation of the Singleton pattern thread safe?


你好,我是七昂,致力于分享C++、操作系统、软件架构、机器学习、效率提升等系列文章。希望我们能一起探索程序员修炼之道,高效学习、高效工作。如果我的创作内容对您有帮助,请点赞关注。如果有问题,欢迎随时与我交流。感谢你的阅读。

标签:AppSettings,C++,实例,线程,构造,单例,static,constructed
From: https://www.cnblogs.com/qiangz/p/17964054

相关文章

  • Python与C++联合编程
    C++代码#编译指令#gcc-otest.so-shared-fPICtest.cg++-otest.so-shared-fPICtest.cc#forc++#include<iostream>usingnamespacestd;extern"C"{//forC++intfoo(inta,intb){cout<<"a:"<<a<<&qu......
  • string 字符串用法C++
    substr() c_str() size()/length()  empty() clear() #include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<vector>usingnamespacestd;intmain(){stringa="abc";......
  • python面向对象之单例模式的使用
    单例模式​ 单例模式(SingletonPattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。​ 比如,某个程序的配置信息存放在一个文件中,客户端通过一个Appconfig的类来读取配置......
  • C++ vector和set排序效率比较
    转自:https://blog.csdn.net/adaptiver/article/details/529257921.介绍vector+sort实际是快排,快速排序是目前已知的所有排序算法中最快的排序算法。例子:#include<vector>#include<set>#include<algorithm>#include<stdio.h>#include<string.h>#include<unistd......
  • C++中for_each用法学习
    转自:chatgpt1.介绍std::for_each是C++标准库中的一个算法,用于对指定范围内的元素执行指定的操作。它的一般形式如下:template<classInputIt,classUnaryFunction>UnaryFunctionfor_each(InputItfirst,InputItlast,UnaryFunctionf);first和last是表示范围的......
  • C++U3-第09课-递归函数的应用
    学习目标 斐波那契数列例题  我们需要求出斐波那契第n项的值是多少【思路分析】我们用递归的方式去求解,当第一项和第二项返回1,否则返回前两项的和当前为第一项和第二项返回1当前不为第一项和第二项返回前两项的和定义n并把n输入,带入到递归求解【参考代......
  • 对单例模式的理解
    【零】引入【1】前言我们知道,经典设计模式总共有23种,但其中只有少数几种被广泛采用。根据我的工作经验,实际常用的可能不超过其中的一半。如果随机找一位程序员,并要求他列举出自己最熟悉的三种设计模式,那么单例模式肯定会是其中之一,这也是今天我们要讨论的。【2】为什么要......
  • C++ 学习宝藏网站分享
    C++学习宝藏网站分享1.C++在线参考手册Cppreferencehttps://zh.cppreference.comC++开发者必备的在线参考手册,是我最常访问的C++网站之一。作为参考手册,不仅包含了语言本身的词法、语法特性,还包含了对C++标准库的介绍:需要include哪个头文件、接口参数/返回值说明......
  • C++源码中司空见惯的PIMPL是什么?
    前言:C++源码中司空见惯的PIMPL是什么?用原始指针、std::unique_ptr和std::shared_ptr指向Implementation,会有什么不同?优缺点是什么?读完这篇文章,相信你能搞懂这种设计方式并将其运用于实践,也将更容易阅读源码。1.PIMPL是什么?PIMPL是PointertoIMPLementation的缩写,意思是指......
  • C++多线程并发(一)--- 线程创建与管理
    目录进程和线程的区别何为并发?C++11线程基本操作C++11新标准多线程支持库std::thread类成员函数std::thread的关键总结C++中多线程创建C++的多线程可以充分利用计算机资源,提高代码运行效率。在这里总结了一些多线程应用过程中的基本概念和用法。进程和线程的区别进程是一......