Отсрочка блокировок и `boost :: lock`

Я читал разницу между lock_guard и unique_lock и обнаружил, что unique_lock — это расширенная версия lock_guard. Так, что с уникальной блокировкой блокировку всегда можно отложить. Я читал этот статья и я наткнулся на boost :: lock.
Я хотел знать, как я могу использовать этот метод. Я попробовал следующее:

boost::mutex mutx;
boost::unique_lock<boost::mutex> guard (mutx,boost::defer_lock);
boost::lock(guard); //too few arguments in function call.

Я был бы признателен, если бы кто-то мог объяснить мне, что делает boost :: lock и как это работает. Спасибо

0

Решение

Цель boost::lock заключается в блокировке нескольких блокировок, гарантирующих отсутствие тупиковой ситуации.

Рассмотрим случай:

unique_lock<...> a, b;

// thread 1
a.lock();
b.lock();
...

// thread 2
b.lock();
a.lock();

Теперь, если первый поток блокирует a заблокировать, а затем вторая нить блокирует b Блокировка, у вас есть проблема: обе блокировки заблокированы, и потоки не будут выполнять ничего, пока один из них не разблокирует блокировку, что невозможно. Это состояние называется тупиком.

boost::lock позволяет избежать этой проблемы, разблокируя все блокировки, которые он уже заблокировал, когда обнаруживает заблокированную блокировку. Реализация для случая двух блокировок может выглядеть примерно так:

template<class L1, class L2>
void lock(L1& l1, L2& l2)
{
while (1) {
if (l1.try_lock()) {
if (l2.try_lock()) {
return;
} else {
l1.unlock();
}
}
// yield (execute another thread) here
}
}
0

Другие решения

Ты имел ввиду

mutex mutx
unique_lock<mutex> guard(mutx,defer_lock);
guard.lock();

?

Когда у вас есть lock_guard или же unique_lockВы перестаете связываться с мьютексом напрямую и работаете над объектом охраны.

0