c++ - 单例线程安全类

标签 c++ thread-safety singleton

我在多线程环境中做的工作很少。所以,我需要知道下面类的 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/

相关文章:

C++ 在 else/if 中声明一个优先级队列?

c++ - 如何将C++程序设置为在Windows启动时自动启动?(通过Windows Service解决方案)

java - 具有与输入处理方法分离的 setter/getter 的类是否可以被视为 "thread-safe"?

java - 从缓存中获取的 Set 中的线程安全性

java - 扩展 log4j/slf4j 记录器

c++ - 创建我的 Game 类的静态单例会引发链接器错误 2001?

swift - 两个相互引用的单例阻止初始化结束

c++ - 'asm' 中的操作数约束不一致

c++ - 处理来自 std::clock() 的 clock_t 溢出

ios - 在 Swift 中使用单例和解析 JSON