为什么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