C++ 这可怕吗?保护类成员的可复制互斥体

C++ 这可怕吗?保护类成员的可复制互斥体,c++,multithreading,C++,Multithreading,我试图通过使用互斥锁使类线程安全 class Container { private: vector<Foo> v; boost::mutex m; public: void add(Foo item) { m.lock(); v.push_back(item); m.unlock(); } }; …然后将容器中的boost::mutex替换为CopyableMutex 这是一件可怕的事情吗?如果没有,那么我

我试图通过使用互斥锁使类线程安全

class Container
{
  private:
   vector<Foo> v;
   boost::mutex m;
  public:
   void add(Foo item)
   {
      m.lock();
      v.push_back(item);
      m.unlock();
   }
};
…然后将
容器中的
boost::mutex
替换为
CopyableMutex

这是一件可怕的事情吗?如果没有,那么我是不是要重新发明轮子?有没有一个库类已经做到了这一点?

是的,这太可怕了

该问题的正确解决方案是为您的容器定制一个复制构造函数和赋值运算符


如果类“太复杂”而无法为其编写自定义副本构造函数,则将线程安全性与容器分开,并使用基类容器,该容器不包含互斥体,也可能不包含派生类“线程安全容器”它包含一个互斥体,并有一个自定义的复制构造函数和赋值操作,只调用自动生成的基类。我相信这样做会使互斥体失效的一个原因是现在使用互斥体的正确方法:

void func()
  {
    std::lock_guard<std::mutex> lock(mtx);
    // do things
  }
void func()
{
标准:锁和防护锁(mtx);
//做事
}
因为您无法返回互斥体,所以无法将其范围扩大到您想要使用它的位置。采用上述使用方式的原因是为了防止在使用锁时出现问题,然后在解锁之前发生某种形式的非故意异常(即确保更可靠的解锁)


不过,我同意其他答案,更好的方法是封装线程安全部分并将其与复杂代码隔离(如果可能的话),然后为较小的类创建显式复制构造函数。

您可以用“坏主意”代替“可怕”(fsvo语法)如果你想指出所有C++都是丑陋的:如果你只需要在那个<代码>容器类中,就把它变成一个私有嵌套类(没有滥用可能)。否则,请在名称中明确说明它不是可复制互斥体(不满足
可复制互斥体a;可复制互斥体b(a);断言(a==b);
),而是在调用复制互斥体时创建新互斥体(这是一个可怕的名称;)如果没有其他原因,这是完全出乎意料的行为。如果我称之为
UniqueMutex
sprowingmutex
或其他什么会更好吗?没有。但也许我只是对这件事太挑剔了。或者(我想我会这么做)我可以将向量和互斥体推送到一个包含的类中,我称之为ThreadSafeVector,并在复杂的容器类中实例化。谢谢
void func()
  {
    std::lock_guard<std::mutex> lock(mtx);
    // do things
  }