我在多线程环境中做的工作很少。所以,我需要知道下面类的 getInstance 函数是否是线程安全的。这是单例类:
//Singleton class
class S {
// intentionally avoided pointer
static S singleObject;
// Private constructor
s ();
s (S &);
s& operator= (const s&);
public:
// return reference of static object
s& getInstance ()
{
return singleObject;
}
/* Normally with static pointer instance, getInstnace look like as
s& getInstace ()
{
// trying to avoid multiple copies of singleObject
lock_mutex ()
if (singleObject == null)
singleObjecct = new S();
unlock_mutex ();
return *singleObject;
}
*/
};
S S::singleObject;
在 getInstance 函数中(未注释),返回静态对象的引用。是否需要线程安全机制?
在第二个 getInstance(注释)中,如果 singleObject 为空,我们创建对象。所以,它需要一个锁定机制,需要同步,对吧?
最佳答案
In getInstance function (un-commented), static object's reference is returned. Does it requires thread-safe mechanism?
只要您不在 main
函数的生命周期之外访问它,或者在其他线程可能具有非同步访问时修改它,那么从任何线程访问它都是安全的。
如果您在 main
开始之前或结束之后进行访问(例如,从另一个静态对象的构造函数或析构函数),则存在它未被初始化或将被初始化的危险那时已经被摧毁了。这就是“惰性初始化”(例如您的第二个版本)的动机。
In second getInstance (commented), we create the object if singleObject is null. So, it requires a locking mechanism and needs to be synchronized, right?
是的,这需要一个锁定机制。对于支持 C++11(或类似)线程模型的编译器,获得像这样的惰性初始化的更简单方法是使用函数静态变量,它将在第一次进入时以线程安全的方式初始化范围:
S& getInstance ()
{
static S singleObject;
return singleObject;
}
这也将避免您的版本的内存泄漏,但会引入一个危险,即它可能会先于其他静态对象被销毁;因此,从静态对象的析构函数访问是不安全的。
通常,C++ 中的静态对象是此类死亡陷阱的雷区(无论您是否尝试将它们包装在某种单例反模式中),最好避免。
关于c++ - 单例线程安全类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11666887/