как не гарантировать мертвую блокировку

Я застрял в одном вопросе в интервью.

Учитывая два потока, и у каждого есть блокировка, как не гарантировать мертвую блокировку.

Мое знание - то, что не легко избежать мертвой блокировки, вот почему я застрял. Может кто-либо давать подсказку.

Спасибо!

5
задан Ofir 18 February 2010 в 09:26
поделиться

6 ответов

Описание немного отсутствует, но если вы наложите порядок блокировки (например, если заблокированы A и B, никогда не блокируйте B, если вы уже не заблокировали A и никогда не отпускайте A, пока B заблокирован), то взаимоблокировки не произойдет.

11
ответ дан 18 December 2019 в 09:49
поделиться

Существуют известные алгоритмы предотвращения взаимоблокировки , которые могут определять, может ли возникновение взаимной блокировки, и предотвращать переход системы в это состояние. Например, Алгоритм Банкира .

3
ответ дан 18 December 2019 в 09:49
поделиться

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

Вы пытаетесь избежать такой ситуации:

A имеет блокировку 1, ожидающую блокировки 2

B имеет блокировку 2, ожидающую блокировки 1

1
ответ дан 18 December 2019 в 09:49
поделиться

Порядок блокировок предпочтительнее обнаружения тайм-аутов / взаимоблокировок, но иногда требуются тайм-ауты, особенно если вы не контролируете все компоненты в системе: следовательно таймаут / обнаружение тупика в базах данных. Если бы все вызывающие были достаточно умны, взаимоблокировки никогда бы не возникли, но обычно не все вызывающие достаточно умны.

1
ответ дан 18 December 2019 в 09:49
поделиться

Вероятно, ваши интервьюеры ожидали ответа WaitForMultipleObjects (). Это Windows API, который блокирует оба (или несколько) ресурсов одновременно.

1
ответ дан 18 December 2019 в 09:49
поделиться

Это означает, что если объект включает управляемый ресурс, нам также придется позаботиться об этом, потому что сборщик мусора не очистит его.

Это ложь. Сборщик мусора будет по-прежнему очищать управляемые ресурсы. Финализаторы также строго предназначены для уборки неуправляемых ресурсов, и, таким образом, вызов SupertFinalize () не повредит вам.

И так как вы новичок в IDisposable образец я буду предвидеть ваш следующий пункт путаницы: написание финализаторов. В C # следует писать финализатор только при работе с совершенно новым видом неуправляемого ресурса. Так, например, при наличии класса, который переносит тип System.Data.SqlClient.SqlConnection как часть уровня доступа к данным, не следует записывать финализатор для этого типа, поскольку вы по-прежнему имеете дело с тем же типом базового неуправляемого ресурса: подключения к базе данных SQL Server. О финализаторе для этого ресурса уже заботится базовый тип SqlConnection.

С другой стороны, если вы создаете поставщика ADO.Net для совершенно нового типа ядра СУБД, вам нужно будет внедрить финализатор в свой класс соединений, потому что это никогда не было сделано раньше.

-121--2786202-

С одной блокировкой невозможно выйти из тупика, пока один не откажется освободить их блокировку - в этом случае ожидающий поток называется голодным. Для нескольких блокировок они должны быть разблокированы в обратном порядке, в котором они были получены, и оба потока должны согласовать заказ.

Чего вы пытаетесь избежать здесь такая ситуация:

A имеет блокировку 1 ожидание на блокировке 2

B имеет блокировку 2 ожидание на блокировке 1

-121--4617123-

Большая работа по параллельному программированию сосредоточена на конструкциях без блокировки. Не точный ответ на ваш вопрос, но, как уже упоминал Эндрю на этой ниве, лучший способ избежать тупиковых ситуаций - вообще не запереться. Многие очень умные люди, работающие над вопросами параллелизма, придерживаются такого мнения.

0
ответ дан 18 December 2019 в 09:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: