Is Meyers#39; implementation of the Singleton pattern thread safe?(Meyers 实现的 Singleton 模式线程安全吗?)
问题描述
Singleton
(Meyers 的 Singleton)线程的以下使用延迟初始化的实现是否安全?
Is the following implementation, using lazy initialization, of Singleton
(Meyers' Singleton) thread safe?
static Singleton& instance()
{
static Singleton s;
return s;
}
如果不是,为什么以及如何使其线程安全?
If not, why and how to make it thread safe?
推荐答案
在 C++11,它是线程安全的.根据标准,§6.7 [stmt.dcl] p4
:
In C++11, it is thread safe. According to the standard, §6.7 [stmt.dcl] p4
:
如果控制进入在变量初始化的同时声明,并发执行应该等待初始化完成.
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
GCC 和 VS 对该功能的支持 (并发的动态初始化和销毁,也称为 MSDN 上的 Magic Statics) 如下:
GCC and VS support for the feature (Dynamic Initialization and Destruction with Concurrency, also known as Magic Statics on MSDN) is as follows:
- Visual Studio:自 Visual Studio 2015
- GCC:自 GCC 4.3 起支持
感谢@Mankarse 和@olen_gam 的评论.
Thanks to @Mankarse and @olen_gam for their comments.
在 C++03 中,此代码不是线程安全的.Meyers 有一篇名为 C++ 和双重检查锁定的风险" 的文章,其中讨论了该模式的线程安全实现,结论或多或少是,(在 C++03 中)围绕实例化方法的完全锁定基本上是确保所有平台上正确并发的最简单方法,而大多数形式的双检查的锁定模式变体可能会受到某些架构上的竞争条件的影响,除非指令与战略性地放置内存屏障交错.
In C++03, this code wasn't thread safe. There is an article by Meyers called "C++ and the Perils of Double-Checked Locking" which discusses thread safe implementations of the pattern, and the conclusion is, more or less, that (in C++03) full locking around the instantiating method is basically the simplest way to ensure proper concurrency on all platforms, while most forms of double-checked locking pattern variants may suffer from race conditions on certain architectures, unless instructions are interleaved with strategically places memory barriers.
这篇关于Meyers 实现的 Singleton 模式线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Meyers 实现的 Singleton 模式线程安全吗?
基础教程推荐
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 设计字符串本地化的最佳方法 2022-01-01
- C++,'if' 表达式中的变量声明 2021-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17