Почему не рекомендуется вызывать метод release() двоичного семафора внутри finally-clause?
Чтобы разблокировать Lock
, рекомендуется вызвать метод unlock()
из выражения finally:
lock.lock();
try{
// critical section which may throw exceptions
} finally {
lock.unlock();
}
Это делается для того, чтобы избежать возможного взаимоблокировки, если исключение выбрано из кода в критическом разделе.
Почему та же практика не рекомендуется для двоичных семафоров в эквивалентных сценариях?
mutex.acquire();
try{
// critical section which may throw exceptions
} finally {
mutex.release();
}
Ответы
Ответ 1
Потому что нет необходимости для потока, ожидание которого на двоичном семафоре будет успешным, чтобы тот, который его сигнализирует. Нити не владеют модулями семафора, как они уже приобрели мьютексы - любой поток может сигнализировать о семафоре (отсюда их общее использование в очереди производителей-потребителей).
Ответ 2
Я бы сказал, что это лучший способ справиться с ними. Семафоры, однако, имеют возможность выпускаться отдельным потоком, поэтому в некоторых расширенных вариантах использования этот шаблон невозможен. (при этом возможно, что вызовы Lock lock()
и unlock()
должны быть в отдельных методах, так что блок finally также невозможен).
Ответ 3
Я бы посоветовал сделать так. Но основное различие между семафором и блокировкой заключается в том, что нет владельцев семафора. Значение потока, который приобрел семафор, может быть не тот, который его освобождает, и это нормально. Я бы предложил всегда выпускать в конечном блоке в какой-то момент