Singleton instance declared as static variable of GetInstance method, is it thread-safe?(单例实例声明为 GetInstance 方法的静态变量,它是线程安全的吗?)
问题描述
我见过单例模式的实现,其中实例变量在 GetInstance 方法中被声明为静态变量.像这样:
I've seen implementations of Singleton patterns where instance variable was declared as static variable in GetInstance method. Like this:
SomeBaseClass &SomeClass::GetInstance()
{
static SomeClass instance;
return instance;
}
我认为这种方法有以下积极方面:
I see following positive sides of this approach:
- 代码更简单,因为只有在第一次调用 GetInstance 时,才由编译器负责创建此对象.
- 代码更安全,因为没有其他方法可以获取对实例的引用,而是使用 GetInstance 方法并且没有其他方法可以更改实例,而是在 GetInstance 方法中.
这种方法的缺点是什么(除了这不是非常面向对象编程)?这是线程安全的吗?
What are the negative sides of this approach (except that this is not very OOP-ish) ? Is this thread-safe?
推荐答案
在 C++11 中它是线程安全的:
In C++11 it is thread safe:
§6.7 [stmt.dcl] p4 如果在初始化变量的同时控制进入声明,则并发执行将等待初始化完成.
§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.
在 C++03 中:
- 在 g++ 下,它是线程安全的.
但这是因为 g++ 明确添加了代码来保证它.
一个问题是,如果您有两个单例,并且它们在构造和销毁过程中尝试互相使用.
One problem is that if you have two singletons and they try and use each other during construction and destruction.
请阅读:查找 C++ 静态初始化顺序问题
这个问题的一个变体是从全局变量的析构函数访问单例.在这种情况下,单例肯定已经被销毁了,但是 get 方法仍然会返回对被销毁对象的引用.
A variation on this problem is if the singleton is accessed from the destructor of a global variable. In this situation the singleton has definitely been destroyed, but the get method will still return a reference to the destroyed object.
有很多方法可以解决这个问题,但它们很乱,不值得做.只是不要从全局变量的析构函数中访问单例.
There are ways around this but they are messy and not worth doing. Just don't access a singleton from the destructor of a global variable.
更安全但丑陋的定义:
我相信你可以添加一些适当的宏来整理这个
A Safer definition but ugly:
I am sure you can add some appropriate macros to tidy this up
SomeBaseClass &SomeClass::GetInstance()
{
#ifdef _WIN32
Start Critical Section Here
#elif defined(__GNUC__) && (__GNUC__ > 3)
// You are OK
#else
#error Add Critical Section for your platform
#endif
static SomeClass instance;
#ifdef _WIN32
END Critical Section Here
#endif
return instance;
}
这篇关于单例实例声明为 GetInstance 方法的静态变量,它是线程安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:单例实例声明为 GetInstance 方法的静态变量,它是线程安全的吗?
基础教程推荐
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 从 std::cin 读取密码 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01