我如何使用类似的std ::矢量 ?(How can I use something like

2019-09-02 09:49发布

我有一个大的,但可能不同,这是同时写入的对象的数量。 我想保护与互斥的访问。 为此,我认为我使用std::vector<std::mutex> ,但这不起作用,因为std::mutex没有复制或移动构造,而std::vector::resize()要求那。

什么是推荐的解决这个难题?

编辑 :难道所有的C ++随机接入容器需要调整大小复制或移动构造函数? 将标准:: deque的帮助?

再次编辑

首先,感谢所有的想法。 我不感兴趣避免mutices和/或将其移动到目标(从我透露更多细节/克制的原因)解决方案。 因此,考虑到我想mutices(其中调整是保证在没有互斥体被锁定的发生)的可调数量的问题,那么,似乎有几种解决方案。

1,我可以用mutices固定数量和使用哈希函数从对象映射到mutices(如Oblivous船长的答案)。 这将导致冲突,但冲突的数量要小,如果mutices的数量大于线程的数量大得多,但仍比对象的数量较小。

2我可以定义(在ComicSansMS的答案)一个包装类,如

struct mutex_wrapper : std::mutex
{
  mutex_wrapper() = default;
  mutex_wrapper(mutex_wrapper const&) noexcept : std::mutex() {}
  bool operator==(mutex_wrapper const&other) noexcept { return this==&other; }
};

并使用std::vector<mutex_wrapper>

3,我可以使用std::unique_ptr<std::mutex>管理单个互斥体(如马蒂亚斯的答案)。 这种方法的问题在于,每一个互斥体被单独分配和堆解除分配。 因此,我更喜欢

4 std::unique_ptr<std::mutex[]> mutices( new std::mutex[n_mutex] );

当一定数目的n_mutex mutices的最初被分配。 如果这个数字后来被发现的不足,我根本

if(need_mutex > n_mutex) {
  mutices.reset( new std::mutex[need_mutex] );
  n_mutex = need_mutex;
}

那么,哪这些(1,2,4)我应该使用?

Answer 1:

vector要求值是可移动的,以便保持值的邻接阵列,因为它生长。 你可以创建一个包含互斥的载体,但你不能做任何事情,可能需要调整其大小。

其他容器没有这样的要求; 无论是deque[forward_]list应该工作,只要你构建互斥到位或者施工过程中,或通过emplace()resize() 如功能insert()push_back()将无法工作。

或者,你可以增加一个间接和存储的额外级别unique_ptr ; 但在另一个回答您的评论表示您认为动态分配的额外成本是不可接受的。



Answer 2:

你可以使用std::unique_ptr<std::mutex>代替std::mutexunique_ptr s为可移动的。



Answer 3:

如果你想创建一个特定长度:

std::vector<std::mutex> mutexes;
...
size_t count = 4;
std::vector<std::mutex> list(count);

mutexes.swap(list);


Answer 4:

我建议使用固定互斥池。 保持一个固定的数组std::mutex ,然后选择要基于锁的哪一个对对象的地址就像你可能会利用哈希表做。

std::array<std::mutex, 32> mutexes;

std::mutex &m = mutexes[hashof(objectPtr) % mutexes.size()];

m.lock();

hashof功能可能是一些简单的在数位移动指针值。 这样,你只需要一次初始化互斥和你避免调整的载体的拷贝。



Answer 5:

如果效率这样的问题,我认为你只有这些改变往往非常小的数据结构。 它是那么可能是更好的使用原子比较和交换(和其他原子操作)而不是使用互斥,具体std::atomic_compare_exchange_strong



Answer 6:

如何声明每个互斥体的指针?

std::vector<std::mutex *> my_mutexes(10)
//Initialize mutexes
for(int i=0;i<10;++i) my_mutexes[i] = new std::mutex();

//Release mutexes
for(int i=0;i<10;++i) delete my_mutexes[i];


文章来源: How can I use something like std::vector?