Существует сценарий, у меня есть два потока, оба используют то же взаимное исключение. Один поток заблокировал взаимное исключение и отказал. Каково было бы взаимоисключающее состояние? Это все еще заблокировано, и второй поток никогда не владеют тем взаимным исключением? Означает ситуацию с мертвой блокировкой?
Редактирование - Также объясняет случай pthread в системах Linux
Поскольку вы не указали, какая ОС, я расскажу вам, что происходит в Win32.
В Win32 второй поток получит WAIT_ABANDONED, когда он перейдет в режим ожидания мьютекса, принадлежащего завершившемуся потоку. Обратите внимание, что получение WAIT_ABANDONED означает, что второй поток получил мьютекс, поэтому взаимоблокировки не будет. Второй поток должен обнаружить результат WAIT_ABANDONED и убедиться, что ресурс, защищенный мьютексом, находится в допустимом состоянии. Если он может обнаружить повреждение и не обнаружит его, можно продолжить. Если нет, то неплохо было бы вызвать какую-нибудь ошибку.
В некоторых реализациях мьютекса невозможно определить, что поток, которому он принадлежит, завершился, и вы попали в тупик.
В некоторых реализациях мьютекса есть способ определить, что является потоком-владельцем, выяснить, что поток-владелец завершен, и затем принять владение мьютексом.
Спасибо за ответ. http://msdn.microsoft.com/en-us/library/ms687032%28VS.85%29.aspx MSDN также сообщает, что освобождает мьютекс, и ожидающие потоки получают статус WAIT_ABANDONED.
Это определенно зависит (по крайней мере) от двух вещей:
Например, в Java синхронизированные
блоки гарантированно освобождаются, когда «поток завершается с объектом» - что бы это ни значило (см. ссылка ). Согласно этой статье :
остановка потока приводит к разблокировке всех мониторов, которые он заблокировал.
Хорошо, stop ()
поток освобождает мониторы, но что, если поток каким-то образом исчезнет, будет ли это «сделано с объектом»? Я нигде не вижу это задокументировано. Но очевидно, что кто-то должен освободить заблокированные мьютексы, иначе они заблокируются; возможно, некоторые мьютексы или среды включают механизмы, которые автоматически освобождают мьютексы, если поток, заблокировавший их, становится несуществующим.
Другой пример: java.util.concurrent.Lock docs рекомендуют использовать оператор finally
для снятия блокировки, чтобы что бы ни случилось с исполняющимся потоком, блокировка снималась бы. Но если поток исчезает до того, как будет выполнен этот оператор finally
, то блокировка никогда не будет снята, и действительно произойдет взаимоблокировка. Конечно, потоки не должны «исчезать» просто так.
Неплохой вопрос!