我有大量但可能会同时写入的对象。我想用互斥锁保护这种访问。为此,我以为我使用了 a std::vector<std::mutex>
,但这不起作用,因为std::mutex
没有复制或移动构造函数,而std::vector::resize()
需要它。
这个难题的推荐解决方案是什么?
编辑:是否所有 C++ 随机访问容器都需要复制或移动构造函数来重新调整大小?std::deque 会有帮助吗?
再次编辑
首先,感谢您的所有想法。我对避免静音和/或将它们移动到对象中的解决方案不感兴趣(我不提供细节/原因)。因此,考虑到我想要一个可调整数量的互斥量(当没有互斥量被锁定时保证发生调整)的问题,那么似乎有几种解决方案。
1我可以使用固定数量的 mutice 并使用散列函数从对象映射到 mutice(如 Oblivous 船长的回答)。这将导致冲突,但是如果 mutice 的数量远大于线程的数量,但仍小于对象的数量,则冲突的数量应该很小。
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>
用来管理单个互斥锁(如 Matthias 的回答)。这种方法的问题在于,每个互斥锁都是在堆上单独分配和取消分配的。因此,我更喜欢
4 std::unique_ptr<std::mutex[]> mutices( new std::mutex[n_mutex] );
当最初分配了一定数量n_mutex
的mutice时。如果以后发现这个数字不够,我干脆
if(need_mutex > n_mutex) {
mutices.reset( new std::mutex[need_mutex] );
n_mutex = need_mutex;
}
那么我应该使用哪一个(1,2,4)?