У меня есть большое, но потенциально изменяющееся количество объектов, которые одновременно записываются. Я хочу защитить этот доступ с помощью мьютексов. С этой целью я решил использовать std::vector<std::mutex>
, но это не сработает, поскольку std::mutex
не имеет конструктора копирования или перемещения, а std::vector::resize()
требует этого.
Какое рекомендуемое решение этой головоломки?
изменить: Все контейнеры с произвольным доступом С++ требуют копирования или перемещения конструкторов для повторной калибровки? Будет ли помощь std:: deque?
снова отредактировать
Во-первых, спасибо за все ваши мысли. Меня не интересуют решения, которые позволяют избежать мутации и/или перемещать их в объекты (я воздержусь от подробностей/причин). Поэтому, учитывая проблему, что я хочу регулируемое количество мутаций (там, где настройка гарантирована, когда нет блокировки мьютекса), тогда, как представляется, существует несколько решений.
1 Я мог бы использовать фиксированное количество мутаций и использовать хеш-функцию для сопоставления объектов с мутациями (как в ответе капитана Обливского). Это приведет к коллизиям, но количество столкновений должно быть небольшим, если число муттирований намного больше числа потоков, но все же меньше числа объектов.
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
муттиз. Если этого числа позже будет найдено недостаточно, я просто
if(need_mutex > n_mutex) {
mutices.reset( new std::mutex[need_mutex] );
n_mutex = need_mutex;
}
Итак, какой из них (1,2,4) я должен использовать?