2013-06-14 4 views
37

Примечание: Этот вопрос касается C++ 11. Ответ на тот же вопрос в C++ 17 (или более поздних версиях), возможно, изменился. Для получения дополнительной информации:Каков наилучший способ блокировки нескольких std :: mutex'es?


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

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

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

ответ

61

Да, вы можете использовать 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); 

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

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

+12

+1 И 'std :: lock' не ограничивается двумя замками. Он может обрабатывать любое число (вплоть до пределов компилятора для вариативных шаблонов). –

+2

Были высказаны опасения относительно эффективности 'std :: lock'. См. Этот ответ: http://stackoverflow.com/a/14525010/576911 для решения этих проблем. –

Смежные вопросы