C ++ operator =在类成员中使用互斥锁

时间:2014-07-28 14:57:43

标签: c++ thread-safety mutex member

我有一个包含一些变量的类,比如一个列表和一个布尔值,可以由几个线程编写,所以用自己的互斥锁保护:

class Motel
{
// [...]
private:
    list<Room> _rooms;
    boost::mutex _rooms_mtx;
    bool _opened;
    boost::mutex _opened_mtx;
}

这段代码的问题是当我需要一个复制构造函数或一个operator =(甚至是自动生成的)时,我想把这个类放在一个地图中:

boost::map<string, Motel> all_motels;
Motel grenoble(...);
all_motels["Grenoble"] = grenoble;

这是禁止的,因为我们无法复制互斥锁:

/usr/include/boost/thread/pthread/mutex.hpp: In copy constructor ‘project::Motel::Motel(const project::Motel&)’:
/usr/include/boost/thread/pthread/mutex.hpp:33:9: error: ‘boost::mutex::mutex(const boost::mutex&)’ is private

在这种情况下我该怎么办? 提前谢谢

4 个答案:

答案 0 :(得分:1)

这里的常见解决方案是使Motel不可复制,并使用Motel在堆上分配new个对象。使用boost::noncopyable和智能指针也是一个好主意。

class Motel : private boost::noncopyable
{
// [...]
private:
    list<Room> _rooms;
    boost::mutex _rooms_mtx;
    bool _opened;
    boost::mutex _opened_mtx;
}

boost::map<string, boost::unique_ptr<Motel> > all_motels;
all_motels["Grenoble"].reset(new Motel(...));

答案 1 :(得分:0)

您无法复制boost :: mutex(您的错误消息显示boost会阻止它,但尝试复制互斥锁是一堆蠕虫)。至少你必须为Motel编写自己的复制构造函数,你必须弄清楚如何处理互斥锁。很可能你想自己创建一个互斥锁。

答案 2 :(得分:0)

您必须提供复制构造函数赋值重载(operator =),它们不会复制互斥锁而是复制数据。请参阅this正在运行的示例:

#include <map>
#include <boost/thread/mutex.hpp>


class foo {
public:
    foo() {}
    foo(foo const& cp)
        : data_(cp.data_) {}

    foo& operator=(foo const& cp) {
        data_ = cp.data_;
        return *this;
    }

private:
    boost::mutex mtx_;

    bool data_;
};


int main(int argc, char* argv[]) {
    std::map<int, foo> bar;
    bar[1] = foo();
    return 0;
}

但是

互斥锁用于共享对象,而不是通过复制它们来完成。因此通常希望不能复制它们。因此,您应该使用shared_ptr(std (c++11)boost)。然后使用shared_ptr的地图:

int main(int argc, char* argv[]) {
    std::map<int, std::shared_ptr<foo>> bar; // untested but you see the point
    bar[1] = std::shared_ptr<foo>(new foo); 
    return 0;
}

答案 3 :(得分:0)

另一个解决方案可能是使用Mutex指针。

private:
    list<Room> _rooms;
    boost::mutex* _rooms_mtx;
    bool _opened;
    boost::mutex* _opened_mtx;
}

顺便说一句,你必须确保尊重这个问题:

  • 是否可以正确创建互斥锁?
  • 是否正确使用了互斥锁?