【问题标题】:C++ Multithreading: Do I need mutex for constructor and destructor?C++ 多线程:构造函数和析构函数是否需要互斥锁?
【发布时间】:2019-03-14 22:21:08
【问题描述】:

对于将被多个线程访问的对象,我是否需要为其构造函数和析构函数设置互斥锁?

我的猜测是我需要在析构函数中使用互斥锁,因为可能有一个线程访问该对象,而另一个线程删除该对象。

另一方面,我想不出为什么我们需要在构造函数中使用互斥锁,因为在对象完全构造之前不能有其他线程访问它。

【问题讨论】:

  • 如果不了解您的实际用例,就无法回答这个问题。例如,如果您在析构函数中使用互斥锁,它不会阻止子析构函数运行(并且可能会在 vtable 上引入竞争)。
  • 对象被构造或销毁时,必须只能由一个线程使用,否则逻辑上存在很大问题。因此,您不必同步 ctor 和 dtor。它没有意义。唯一有意义的同步是加入由该对象产生的线程。
  • 如果有一个线程在等待访问一个正在反初始化的对象,我称之为bug。
  • 如果你把互斥锁放在析构函数中为时已晚,你必须提前确保析构函数只被调用一次。构造函数也一样,它应该只运行一次,而不是一次只在一个线程中运行。请举个例子
  • 如果您有一个线程访问该对象,而另一个线程正在删除该对象,则您有一个基本的设计问题。互斥锁不会拯救你。一种可能性是对象被销毁,然后另一个线程尝试访问它。

标签: c++ multithreading


【解决方案1】:

您无法在对象被构造之前共享它。如果它没有被共享,那么只有一个线程使用它。结论没有必要在构造函数中同步任何东西(除非你正在生成一个新线程)。

现在析构函数仅在所有强引用结束其生命周期时才被调用。这意味着当执行析构函数时,最后一个强引用只是被清理了。这再次意味着只有一个线程在使用对象,因此没有同步的意义。

如果出于某种神奇的原因,您将在构造函数或析构函数中出现竞争条件,则该错误必须在对象的所有者中。

我能想象的唯一在析构函数中有意义的同步是加入线程期货(由这个对象产生)或履行承诺。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 2010-12-16
    相关资源
    最近更新 更多