Почему не рекомендуется вызывать метод release() бинарного семафора из блока finally?

Чтобы убедиться, что 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();
}

person Marco Lackovic    schedule 02.02.2012    source источник


Ответы (3)


Потому что нет необходимости, чтобы поток, чье ожидание на двоичном семафоре было успешным, сигнализировал об этом. Потоки не владеют единицами семафора, как приобретенные мьютексы - любой поток может сигнализировать о семафоре (отсюда их обычное использование в очередях производитель-потребитель).

person Martin James    schedule 02.02.2012

Я бы сказал, что это, как правило, лучший способ справиться с ними. Однако семафоры могут быть освобождены отдельным потоком, поэтому в некоторых сложных случаях использования этот шаблон невозможен. (тем не менее, вызовы Lock lock() и unlock() могут находиться в отдельных методах, так что блок finally также невозможен).

person jtahlborn    schedule 02.02.2012

Я бы советовал делать так. Но главное отличие семафора от блокировки в том, что у семафора нет владельцев. Это означает, что поток, получивший семафор, может не быть тем, кто его освободил, и это нормально. Я бы посоветовал всегда выпускать в блоке finally в какой-то момент

person John Vint    schedule 02.02.2012