0

我一直在阅读有关线程安全单例的信息,我发现到处都有一个 getInstance() 方法,如下所示:

Singleton* getInstance()
{
    if ( !initialized )
    {
        lock();
        if ( !initialized )
        {
            instance = new Singleton();
            initialized = true;
        }
        unlock();
    }

    return instance;
}
  • 这实际上是线程安全的吗?
  • 我是否遗漏了什么,或者这个函数有很小的机会返回一个未初始化的实例,因为“初始化”可能会在实例之前重新排序和设置?

这篇文章的主题略有不同,但最佳答案描述了为什么我认为上面的代码不是线程安全的:

为什么 volatile 在多线程 C 或 C++ 编程中没有用?

4

3 回答 3

4

不是一个好主意。寻找双重检查锁定。例如:

http://www.drdobbs.com/cpp/c-and-the-perils-of-double-checked-locki/184405726

http://www.drdobbs.com/cpp/c-and-the-perils-of-double-checked-locki/184405772

于 2012-08-12T09:28:22.800 回答
0

它确实不是线程安全的,因为在指针返回后,您仍然可以使用它,尽管互斥锁再次解锁。

您可以做的是使从单例继承的子类线程安全。那你就可以走了。

于 2012-08-12T09:58:36.853 回答
0

下面是使用双重检查和临时变量的线程安全单例的代码。一个临时变量用于先完全构造对象,然后将其分配给 pInstance。

Singleton* Singleton::instance() {
   if (pInstance == 0) {
      Lock lock;
      if (pInstance == 0) {
         Singleton* temp = new Singleton; // initialize to temp
         pInstance = temp; // assign temp to pInstance
      }
   }
   return pInstance;
}
于 2022-01-06T03:46:51.327 回答