Сбой нитки с заблокированным Mutex - PullRequest
5 голосов
/ 02 июля 2010

Есть сценарий, у меня два потока, оба используют один мьютекс. Одна нить заблокировала мьютекс и рухнула. Каким будет состояние мьютекса? Он все еще заблокирован, и второй поток никогда не владеет этим мьютексом? Значит тупиковая ситуация?

Редактировать - также объяснить случай pthread в системах Linux

Ответы [ 3 ]

4 голосов
/ 02 июля 2010

Поскольку вы не указали, какая ОС, я расскажу вам, что происходит в Win32.

В Win32 второй поток получит WAIT_ABANDONED, когда он будет ждать мьютекса, принадлежащего завершившемуся потоку. Обратите внимание, что получение WAIT_ABANDONED означает, что второй поток получил мьютекс, поэтому не будет взаимоблокировки. Второй поток должен обнаружить результат WAIT_ABANDONED и убедиться, что ресурс, защищенный мьютексом, находится в действительном состоянии. , Если он может обнаружить коррупцию и не обнаружит ее, можно продолжить. Если нет, то стоит выдвинуть какую-то ошибку.

В некоторых реализациях мьютекса нет способа обнаружить, что поток, которому он принадлежит, завершился, и вы оказались в тупике.

В некоторых реализациях мьютекса есть способ определить, что такое поток-владелец, выяснить, что поток-владелец завершен, и затем получить право собственности на мьютекс.

2 голосов
/ 02 июля 2010

Это, безусловно, зависит (как минимум) от двух вещей:

  • Как реализован мьютекс и
  • Как происходит сбой потока (он вызывает исключение или просто «исчезает»).

Например, в Java synchronized блоки гарантированно освобождаются, когда «поток завершен с объектом» - что бы это ни значило (см. ссылка ). Согласно этой статье:

При остановке потока он разблокирует все заблокированные мониторы.

Хорошо, stop() Если поток освобождает мониторы, но что, если поток просто каким-то образом исчезает, тогда он "завершается с объектом"? Я не вижу это нигде документально. Но очевидно, что кто-то должен освободить заблокированные мьютексы, иначе они могут зайти в тупик; возможно, некоторые мьютексы или среды включают механизмы, которые автоматически освобождают мьютексы, если поток, который их заблокировал, становится несуществующим.

Другой пример: java.util.concurrent.Lock docs рекомендует использовать оператор finally для снятия блокировки, чтобы, что бы ни случилось с исполняющим потоком, блокировка будет снята. Но если поток исчезнет до того, как будет выполнен этот оператор finally, блокировка никогда не будет снята и действительно произойдет взаимоблокировка. Конечно, потоки не должны так просто «исчезать».

Неплохой вопрос!

0 голосов
/ 02 июля 2010

Спасибо за ваш ответ. http://msdn.microsoft.com/en-us/library/ms687032%28VS.85%29.aspx MSDN также сообщает, что освобождает мьютекс, и ожидающие потоки получают статус WAIT_ABANDONED.

...