专业编程基础技术教程

网站首页 > 基础教程 正文

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

ccvgpt 2024-10-12 13:57:24 基础教程 7 ℃
const bg::AppSettings& bg::AppSettings::GetInstance()
{
    static AppSettings instance;
    return instance;
}

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

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

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

  • 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? (https://stackoverflow.com/questions/34457432/c11-singleton-static-variable-is-thread-safe-why)

[2]Is Meyers' implementation of the Singleton pattern thread safe? (https://stackoverflow.com/questions/1661529/is-meyers-implementation-of-the-singleton-pattern-thread-safe)


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


知乎、公众号:七昂的技术之旅

最近发表
标签列表