为什么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++、操作系统、软件架构、机器学习、效率提升等系列文章。希望我们能一起探索程序员修炼之道,高效学习、高效工作。如果我的创作内容对您有帮助,请点赞关注。如果有问题,欢迎随时与我交流。感谢你的阅读。

为什么C++ 单例局部static初始化是线程安全的?的更多相关文章

  1. JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

    JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...

  2. 单例 与 static

    单例的构造器是private的,不能直接用new 创建对象.static虽然可以随时使用,但是还是有被重新创建的可能. 举个例子,你希望任何时候有一个class A的实例就可以了class B {  ...

  3. dispatch_once单例初始化

    static GHCache *instance = nil; /** *  单例,静态初始化方法 * *  @return 返回一个单例 */ + (GHCache*)shareCache{ sta ...

  4. 【Spring源码分析】非懒加载的单例Bean初始化过程(下篇)

    doCreateBean方法 上文[Spring源码分析]非懒加载的单例Bean初始化过程(上篇),分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的.先贴一下 ...

  5. 【Spring源码分析】非懒加载的单例Bean初始化前后的一些操作

    前言 之前两篇文章[Spring源码分析]非懒加载的单例Bean初始化过程(上篇)和[Spring源码分析]非懒加载的单例Bean初始化过程(下篇)比较详细地分析了非懒加载的单例Bean的初始化过程, ...

  6. Spring源码分析:非懒加载的单例Bean初始化前后的一些操作

    之前两篇文章Spring源码分析:非懒加载的单例Bean初始化过程(上)和Spring源码分析:非懒加载的单例Bean初始化过程(下)比较详细地分析了非懒加载的单例Bean的初始化过程,整个流程始于A ...

  7. Spring源码分析:非懒加载的单例Bean初始化过程(下)

    上文Spring源码分析:非懒加载的单例Bean初始化过程(上),分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的.先贴一下AbstractAutowireC ...

  8. Java基础 static限定符的使用 以及【 static实现的 singleton(单例)设计模式】

    static实现的 singleton(单例)设计模式 /** static实现的 singleton设计模式 , 使得一个类只能够创建一个static对象 */ 模板设计结构: package Co ...

  9. Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean

    Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean 七千字长文深刻解读,Spirng中是如何初始化单例bean的,和面试中最常问的Sprin ...

  10. java 单例

    Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍两种:懒汉式单例.饿汉式单例. 饿汉式和懒汉式区别 从名字上来说,饿汉和懒汉, 饿汉就是类一旦加载,就把单例初始化完成,保证 ...

随机推荐

  1. 洛谷P5020

    水一道绿题... #include<iostream> #include<utility> #include<algorithm> using namespace ...

  2. 修改Jenkins默认管理员admin密码

    1.删除Jenkins目录下config.xml文件中下面代码,并保存文件. <useSecurity>true</useSecurity><authorizationS ...

  3. MySQL ibdata1文件太大的解决办法

    在MySQL数据库中,如果不指定innodb_file_per_table=1参数单独保存每个表的数据,MySQL的数据都会存放在ibdata1文件里,时间久了这个文件就会变的非常大. 下面是参考网上 ...

  4. [oeasy]python0127_中文系统_gbk_BIG5_南极星_内码转化

    中文系统bgk 回忆上次内容 汉字字形通过 点阵式打字机 像素级寻址的屏幕 进入了计算机的世界   ​   添加图片注释,不超过 140 字(可选)   在海峡对岸的台湾同胞 也进入了汉字时代   他 ...

  5. oeasy教您玩转linux010206toilet

    我们来回顾一下 上一部分我们都讲了什么? 用apt查询并下载了figlet 玩了一下字符画 设置了字符画的字体 但是没有修改颜色 这次我们来找找另一个命令toilet apt search toile ...

  6. TIER 2: Oopsie

    TIER 2: Oopsie Web 渗透 此次靶机结合前面知识,非常简单: nmap 扫描,发现 22 和 80 端口开放 服务 80 的 HTTP 服务 之后使用继续 Web 渗透: 使用 Wap ...

  7. 硬件开发笔记(二十八):TPS54331电源设计(一):5V电源供电原理图设计

    前言   电源供电电路设计很重要,为了更好的给对硬件设计有需求的人,特意将电源设计的基础过程描述出来.  本篇描述设计常用的12V转5V电路3A.   TPS54331(DC-DC稳压器) 概述    ...

  8. 对精确率(P)、召回率(R)、F1值的理解以及对应的实现

    对精确率.召回率.F1值的理解 算法理解 在机器学习中,P.R和F1值在各种评测中很常见,那么到底什么是P.R.F1值呢,怎么理解呢,困扰了很多人,下面给我对P.R.F1值的理解, 首先,我们先看一个 ...

  9. adb对安卓app进行抓包(ip连接设备)

    adb对安卓app进行抓包(ip连接设备) 一,首先将安卓设备的开发者模式打开,提示允许adb调试 二,自己的笔记本要和安卓设备在同一个网段下(同连一个WiFi就可以了) 三,在笔记本上根据ip来连接 ...

  10. 【Spring-Cloud】Nacos2.0.3 单系统集群部署问题汇总

    1.强制要求JDK8版本 且 64位 C:\Users\Administrator\Desktop\Nacos-Server\Nacos-2.0.3-8848\bin>java -version ...