С++ std::mutex
не имеет конструктора перемещения. Существует хорошая причина для этого. В принципе, сами конструкторы перемещения обычно не являются потокобезопасными, и вся точка мьютекса состоит в том, что несколько потоков будут пытаться получить к нему доступ одновременно.
Несчастная импликация заключается в том, что мьютекс нельзя напрямую помещать в контейнер. Контейнеры должны иметь возможность безопасно перемещать свое содержимое, и вы не можете сделать это с помощью мьютекса.
Легкий выход - просто защитить весь контейнер с помощью одного отдельного мьютекса. Но предположим, что мне нужен более тонкий контроль? Если я реализую базу данных через контейнер (например: std::map
), представляется разумной необходимость блокировки отдельных записей, а не только всей базы данных.
Следующее, что приходит в голову, - это взломать проблему, используя std::unique_ptr
. Это будет скомпилировано, но на самом деле это не изменяет основную проблему, не так ли? Сценарий, в котором возникает проблема с перемещением, заключается в том, что thread1
создает изменение контейнера, которое вызывает перемещение записи, а thread2
находится в середине использования этой записи контейнера. В этом случае thread2
может так же легко привести к уничтожению записи или умному указателю. Кажется, что бы вы ни делали, вам нужно заблокировать весь контейнер с помощью мьютекса, прежде чем что-либо делать.
Кажется, что для подобных вещей должна быть известная идиома.