Мертвые и живые блокировки
Мертвые и живые блокировки
Потом ударили морозы. Замерзло все, лиса ушла в кредит. Медведь же вмерз в дупло И до сих пор глядит. Б. Гребенщиков. |
Решив проблему взаимоисключения для одиночных разделяемых ресурсов, мы еще не можем расслабляться. Дело в том, что если мы используем любые механизмы взаимоисключения для доступа к нескольким различным ресурсам, может возникнуть специфическая проблема, называемая мертвой блокировкой (dead lock).
Рассмотрим две нити, каждая из которых работает с двумя различными ресурсами одновременно. Например, одна нить копирует данные со стриммера на кассету Exabyte, а другая — в обратном направлении. Доступ к стриммеру контролируется флаговой переменной flag1, а к кассете — flag2 (вместо флаговых переменных могут использоваться и более сложные средства взаимоисключения).
Первая нить сначала устанавливает flag1, затем fiag2, вторая поступает наоборот. Поэтому, если вторая нить получит управление и защелкнет flag2 в промежутке между соответствующими операциями первой нити, то мы получим мертвую блокировку (Рисунок 7.1) — первая нить никогда не освободит flag1, потому что стоит в очереди у переменной flag2, занятой второй нитью, которая стоит в очереди у flagi, занятой первой.