【问题标题】:C++ 11: Mutex & Condition Variable Cannot be CopiedC++ 11:互斥量和条件变量无法复制
【发布时间】:2019-05-19 02:10:55
【问题描述】:

我是 C++ 11 的新手并使用线程。我遇到了一个无法复制互斥锁和条件变量对象的场景。代码是这样的......

class producer {

   public: 
      producer(mutex m, condition_variable cv) 
      {
           mut = m;    // ERROR
           cvar = cv;   // ERROR
       }

    private:
         mutex mut;
         condition_variable cvar;
}

当试图在构造函数中复制变量时,它给出了错误。似乎复制构造函数设置为删除 mutex 和 cv。

有办法克服吗?我想要一个生产者和消费者类,然后从 ma​​in 函数传递互斥量和 cv。

所以基本上来自主函数的调用应该看起来像......

int main ()
{
    mutex m;
    condition_variable cv;
    //Initialize mutex & cv
    producer prod(m, cv);
}

【问题讨论】:

  • 想想拥有多个互斥体副本会带来什么样的恐怖。您可以围绕共享指针之类的东西构建内部,以便所有副本都引用相同的底层互斥体,但这会对只想使用互斥体而不传递它的每个人造成惩罚。
  • 互斥锁旨在保护资源。与其传递互斥锁,不如考虑将资源和互斥锁封装在一个类中,然后传递该类的一个实例。在一天结束时,您将遇到与互斥锁不可复制的相同问题,封装对象也是如此,但是更好地描述了意图,您可以使用该类来防止访问资源而不获取互斥锁.
  • 当你有mutex数据成员时如何写你的特殊成员:stackoverflow.com/a/29988626/576911

标签: c++ c++11


【解决方案1】:

不,这是不可能的。在 C++ 中添加了功能以启用此功能(非复制)。

如果您考虑实现,您是在更改某种内核对象吗?会不会一样。可能不是。这是设计使然。

【讨论】:

    【解决方案2】:

    您需要存储对mutexcondition_variable 的引用或指针。

    class producer {
    public: 
      producer(mutex & m, condition_variable & cv) 
        : _mut{m}
        , _cvar{cv}
      {
      }
    
    private:
         mutex & mut;
         condition_variable & cvar;
    };
    

    您可以使用std::shared_ptrs,因为这样可以让您的实例对mutexcondition_variable 拥有强大的所有权,但这样可以更快地输入。

    【讨论】:

    • 这种方法有一个缺点:无法重新定位引用,因此无法分配 producer。根据您的用例,可能不是问题。
    【解决方案3】:

    这在设计上是不可能的。

    复制互斥体意味着什么?应该怎么做?

    假设您等待互斥锁 A,而某些主体将互斥锁 A 复制到互斥锁 B。 你还在等A还是等B?还是对他们两个?不,您仍然应该等待 A。 所以其他互斥量B不能是A的副本。所以复制被删除。

    移动操作是有意义的,但是由于互斥体是静态分配的,因此如果不更改地址就不可能移动它们——这对于等待互斥体的人来说是一场噩梦。因此移动操作也被删除了。

    同样的条件也适用于条件变量。

    要克服这些问题,您可以使用指向互斥锁和条件变量的指针。比如说,如果您想要一个简单的设计,请将它们存储为 std::shared_ptr<std::mutex>std::shared_ptr<std::condition_variable>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      • 2015-12-29
      • 1970-01-01
      • 2010-11-06
      • 2018-10-06
      相关资源
      最近更新 更多