【问题标题】:mutex as class member互斥锁作为类成员
【发布时间】:2011-08-22 06:26:59
【问题描述】:
 class temp
 {
    boost::mutex mx;
    void CriticalCode() {
        boost::mutex::scoped_lock scoped_lock(mx); 
        //Do Something
        return;
    }
 }
  1. 如果这个类是在堆上分配的 (temp* T = new temp()),这是否是线程安全的(对于每个实例,而不是所有实例一起)?

  2. 如果我创建boost::mutex mx -> boost::mutex* mx,并在构造函数中分配它以便在堆上分配,代码是否也是线程安全的?

  3. 如果对 1 和 2 的回答是否定的,我怎样才能使每个实例线程安全?

【问题讨论】:

  • 当人们可以谈论“自动”和“动态”分配时,为什么还要谈论“堆栈”和“堆”。
  • 关于第 2 点,完全没有必要这样做。使其成为指针的唯一原因(即使那样,我也会将其设为引用)是在构造过程中将互斥锁传递给实例 - 即您有一个希望所有实例都使用的互斥锁。

标签: c++ multithreading boost mutex


【解决方案1】:

是的,CriticalCode() 方法在这两种情况下都是线程安全的。

【讨论】:

    【解决方案2】:

    1)如果这个类是在堆上分配的 (temp* T = new temp()) ,这是否是线程安全的(对于每个实例,不是所有实例都在一起?

    是的。由于 mx 不是该类的静态成员,因此该类的每​​个实例都会有一个锁。

    2)如果我让 boost::mutex mx -> boost::mutex* mx ,并在构造函数中分配它,所以它会在堆上分配,代码也是线程安全的吗?强>

    是的。但线程安全仅在每个实例的基础上。

    3)如果现在回答 1 和 2,我怎样才能使每个实例线程安全?

    答案是肯定的,所以你很好。

    万一其他人想知道如何使用一个锁使所有实例线程安全——您可以使 mx 成为该类的静态变量。

    【讨论】:

    • 关于您的最后一条评论,这在很大程度上取决于静态实例的构造位置和方式(即惰性不是固有的线程安全!)。如果你最终采用这种方法 - 你真的需要审查你的设计。
    • 我明白了。我不在惰性静态变量之上。我的计算机科学家确实告诉我,该术语意味着在实际写入变量之前不会完成分配。这对我来说听起来仍然是线程安全的,但我可能遗漏了一些东西,你能告诉我更多吗?
    • 在给定的类中有两种使用静态的方法。一种方法是直接将它们声明为静态成员,然后在翻译单元中实际定义它们(这里的问题是你依赖于初始化的顺序 - 这不能保证)。解决方法是将对象声明为类的静态函数中的静态对象,并返回对该静态实例的引用——这就是我所说的延迟初始化。然而,这并不是线程安全的(标准没有指定线程,因此没有指定谁构造)。
    • ...即如果两个线程进入静态函数获取锁,并且之前没有人调用过这个函数,则无法保证谁构造。解决此问题的一种方法是在创建线程之前进行某种全局初始化,该线程调用此静态函数来构造互斥锁...其他选项是在构造temp 对象时简单地传入互斥锁并且只有一个引用 temp 中的互斥锁。
    【解决方案3】:

    存储位置与任何东西无关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-23
      • 2021-07-19
      相关资源
      最近更新 更多