Условия возникновения тупиков
В 1971 г. Коффман, Элфик и Шошани сформулировали следующие четыре условия для возникновения тупиков.
1. Условие взаимоисключения (Mutual exclusion). Каждый ресурс выделен в точности одному процессу или доступен. Процессы требуют предоставления им монопольного управления ресурсами, которые им выделяются.
2. Условие ожидания ресурсов (Hold and wait). Процессы удерживают за собой ресурсы, уже выделенные им, ожидая в то же время выделения дополнительных ресурсов (которые при этом обычно удерживаются другими процессами).
3. Условие неперераспределяемости (No preemtion). Ресурс, данный ранее, не может быть принудительно забран у процесса. Освобождены они могут быть только процессом, который их удерживает.
4. Условие кругового ожидания (Circular wait). Существует кольцевая цепь процессов, в которой каждый процесс удерживает за собой один или более ресурсов, требующихся другим процессам цепи.
Для тупика необходимо выполнение всех четырехусловий.
Обычно тупик моделируется прямым графом, наподобие того, что изображен на рис. 7.1, состоящим из узлов двух видов: прямоугольников процессов и эллипсов ресурсов. Стрелки, направленные от ресурса к процессу, показывают, что ресурс выделен данному процессу.
Основные направления борьбы с тупиками.
В связи с проблемой тупиков были выполнено много интересных исследований в области информатики и операционных систем.
Основные направления борьбы с тупиками:
1. Игнорировать данную проблему
2. Обнаружение тупиков
3. Восстановление после тупиков
4. Обход тупиков за счет тщательного выделения ресурсов
5. Предотвращение тупиков за счет нарушения одного из условий возникновения тупиков.
Алгоритм страуса
Простейший подход - игнорировать проблему тупиков. Различные люди реагируют на подобную стратегию по-разному. Математики находят ее неприемлемой и утверждают, что тупики должны быть предотвращены любой ценой. Инженеры задают вопрос: как часто возникает данная проблема и как часто система виснет по другим причинам? Если тупик встречается раз в пять лет, но аварийный останов системы из-за отказов оборудования, ошибок компиляторов или ОС происходит раз в месяц, большинство инженеров не пожелают пожертвовать производительностью или удобством, чтобы ликвидировать тупик.
Например, ОС Unix, имеющая в ядре ряд массивов фиксированной размерности, потенциально страдает от тупиков, даже если они не обнаружены. Например, суммарное число процессов в системе определяется размерностью таблицы процессов. Если таблица заполнена, вероятность этого ничтожна, но такое может произойти, то для программы, которая делает вызов fork, резонно подождать некоторое время и попытаться осуществить этот вызов вновь. Следует ли отказываться от вызова fork, чтобы решить эту проблему?
Максимальное число открытых файлов аналогичным образом ограничено размером таблицы индексных узлов. С ними может произойти аналогичная ситуация. Пространство выгрузки на диске - другой лимитируемый ресурс. Фактически любая таблица в ОС - конечный ресурс.
Подход Unix состоит в том, чтобы игнорировать данную проблему в предположении, что большинство пользователей предпочтут случайный тупик нелепым правилам заставляющих их иметь один процесс, один открытый файл и т.п. ... Таким образом, мы сталкиваемся с нежелательным выбором между строгостью и удобством. Трудно найти общее, устраивающее всех решение.
Обнаружение тупиков
Обнаружение тупика это установление факта, что возникла тупиковая ситуация и определение процессов и ресурсов, вовлеченных в эту ситуацию. Как правило, алгоритмы обнаружения применяются, когда выполнены первые три необходимых условия возникновения тупиковой ситуации. Затем проверяется наличие режима кругового ожидания. При этом активно используются графы распределения ресурсов.
Существуют и другие способы обнаружения тупиков, применимые также в ситуациях, когда имеется несколько ресурсов каждого типа. Так в [22] описан способ, называемый редукцией графа распределения ресурсов, а в [12] матричный алгоритм.