Какой лучший способ заблокировать несколько std:: mutex'es?

Если мы хотим заблокировать несколько std::mutex 'es, мы используем std::lock(). Но std::lock() не предоставляет функцию RAII.

Если мы хотим заблокировать std::mutex в RAII-способе, мы используем std::lock_guard. Но std::lock_guard не может заблокировать несколько std::mutex 'es безопасно.

Есть ли способ воспользоваться преимуществами обоих методов, чтобы заблокировать несколько std::mutex 'es в режиме RAII?

Ответ 1

Да, вы можете использовать std::unique_lock с std::defer_lock. Он сообщает уникальному_блоку, чтобы он не блокировал мьютекс немедленно, а для создания обертки RAII.

std::unique_lock<std::mutex> lk1(mutex1, std::defer_lock);
std::unique_lock<std::mutex> lk2(mutex2, std::defer_lock);
std::lock(lk1, lk2);

Из-за своей вариационной природы std::lock не привязан к двум аргументам, но может использоваться с таким количеством аргументов, как поддержка вашего компилятора.

Ховард Хиннант также отметил интересный факт о производительности, вы можете проверить эту ссылку, если вы заинтересованы. Он рассматривает проблемы производительности и показывает, что std::lock можно эффективно реализовать, я также могу рекомендовать прочитать все комментарии в этом сообщении.