【问题标题】:How to use a boost::mutex as the mapped type in std::map?如何使用 boost::mutex 作为 std::map 中的映射类型?
【发布时间】:2016-04-07 06:28:16
【问题描述】:

我想像这样将键/索引锁定在另一个地图中:

std::map<int, boost::mutex> pointCloudsMutexes_;
pointCloudsMutexes_[index].lock();

但是,我收到以下错误:

/usr/include/c++/4.8/bits/stl_pair.h:113: error: no matching function for call to 'boost::mutex::mutex(const boost::mutex&)'
       : first(__a), second(__b) { }
                               ^

它似乎适用于std::vector,但不适用于std::map。我做错了什么?

【问题讨论】:

  • 有人想知道是什么要求导致了设计决策,即互斥体映射是一种有效的解决方案。可能有一种更优雅的方式来实现您想要的。
  • 并发哈希图
  • 这种设计不会是并发哈希映射。这将是互斥锁的非并发映射。您需要包装整个地图并仅使用一个互斥锁来保护它。
  • 那是糟糕的设计。这种访问一个键/值的方式我需要锁定整个互斥锁?
  • 为了找到或插入一个,是的。否则,您在执行上述任何一项操作时都会出现数据竞争。

标签: c++ boost mutex stdmap boost-mutex


【解决方案1】:

在 C++11 之前的 C++ 中,在调用 operator[] 时,std::map 的映射类型必须既是默认可构造的,又是可复制构造的。但是,boost::mutex 被明确设计为不可复制构造,因为通常不清楚复制互斥体的语义应该是什么。由于boost::mutex 不可复制,使用pointCloudsMutexes_[index] 插入此类值无法编译。

最好的解决方法是使用一些指向boost::mutex 的共享指针作为映射类型,例如:

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

struct MyMutexWrapper {
    MyMutexWrapper() : ptr(new boost::mutex()) {}
    void lock() { ptr->lock(); }
    void unlock() { ptr->unlock(); }
    boost::shared_ptr<boost::mutex> ptr;
};

int main() {
    int const index = 42;
    std::map<int, MyMutexWrapper> pm;
    pm[index].lock();
}

PS:C++11 删除了映射类型是可复制构造的要求。

【讨论】:

  • 你说"C++11 removed the requirement for the mapped type to be copy-constructible",所以作者的代码应该在c++11下编译?
  • @AlexeyAndronov 是的。刚刚尝试了问题中的代码示例,当索引为int 时,它确实可以编译。
  • 它不在我的 MSVS2015 update2 上,std::mapstd::mutex 虽然 X_x
  • 非常符合std::mutex在线herehere
  • 你说得对,我在玩pointCloudsMutexes_.emplace(index, std::mutex());,它仍然无法编译,但这是另一个问题(似乎链接到std::pair
【解决方案2】:

Map 需要一个拷贝构造函数,但不幸的是boost::mutex 没有公共拷贝构造函数。互斥锁声明如下:

class mutex
{
private:
    pthread_mutex_t m;
public:
    BOOST_THREAD_NO_COPYABLE(mutex)

我认为矢量也不起作用,它应该有同样的问题。你能把push_backboost::mutex 变成向量吗?

【讨论】:

  • 互斥体互斥体不可复制并不是“不幸的”——这是非常幸运的。它表示一个不能移动的底层数据结构。
  • @Richard 我同意:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2017-03-21
  • 2015-11-03
相关资源
最近更新 更多