
- •Глава 6 Взаимоблокировка и голодание
- •6.1. Принципы взаимного блокирования
- •Повторно используемые ресурсы
- •Расходуемые ресурсы
- •Условия возникновения взаимоблокировок
- •6.2. Предотвращение взаимоблокировок
- •Взаимоисключения
- •Удержание и ожидание
- •Отсутствие перераспределения
- •Циклическое ожидание
- •6.3. Устранение взаимоблокировок
- •Запрещение запуска процесса
- •Запрет выделения ресурса
- •А.) Глобальная структура данных
- •6.4. Обнаружение взаимоблокировок
- •Алгоритм обнаружения взаимоблокировки
- •Восстановление
- •6.5 Интегрированные стратегии разрешения взаимоблокировок
- •6.6. Задача об обедающих философах
- •6.7. Механизмы параллельных вычислений в unix
- •Сообщения
- •Разделяемая память
- •Семафоры
- •Сигналы
- •6.8. Прщийвы синхронизации потоков solaris
- •Блокировки взаимоисключений
- •Семафоры
- •Блокировки читатели/писатель
- •Переменные условий
- •6.9. Механизмы параллельных вычислений в windows 2000
- •6.10. Резюме, ключевые термины и контрольные вопросы
- •Контрольные вопросы
- •6.11. Рекомендуемая литература
- •6.12. Задачи
Глава 6 Взаимоблокировка и голодание
Принципы взаимного блокирования.
Предотвращение взаимоблокировок.
Устранение взаимоблокировок.
Обнаружение взаимоблокировок.
Интегрированные стратегии разрешения взаимоблокировок.
Задача об обедающих философах.
Механизмы параллельных вычислений в UNIX.
Примитивы синхронизации потоков Solaris.
Механизмы параллельных вычислений в Windows 2000.
Резюме, ключевые термины и контрольные вопросы.
Рекомендуемая литература.
Задачи.
Эта глава продолжает рассмотрение параллельных вычислений и посвящена — двум проблемам, доставляющим основные неприятности при работе с параллельными вычислениями: взаимоблокировкам и голоданию. Глава начнется с изложения основных принципов взаимоблокировок, а затем мы узнаем, как их можно предотвратить, обнаружить и устранить. Под конец мы рассмотрим еще одну классическую задачу, иллюстрирующую вопросы синхронизации и взаимоблокировки, а именно — задачу об обедающих философах.
Как и в главе 5, "Параллельные вычисления: взаимоисключения и многозадачность", здесь мы ограничимся рассмотрением проблем в единой системе; распределенным системам посвящена глава 14, "Управление распределенными процессами".
6.1. Принципы взаимного блокирования
Взаимное блокирование (deadlock1) можно определить как постоянное блокирование множества процессов, которые либо конкурируют в борьбе за системные ресурсы, либо сообщаются один с другим. В отличие от других проблем, возникающих в процессе управления параллельными вычислениями, данная проблема в общем случае эффективного решения не имеет.
Все взаимоблокировки предполагают наличие конфликта в борьбе за ресурсы между двумя или несколькими процессами. Наиболее ярким примером может служить транспортная взаимоблокировка. На рис. 6.1 показана ситуация, когда четыре автомобиля должны примерно одновременно пересечь перекресток. Четыре квадранта перекрестка представляют собой ресурсы, которые требуются процессам. В частности, для успешного пересечения перекрестка всеми четырьмя автомобилями необходимые ресурсы выглядят следующим образом:
автомобилю, движущемуся на север, нужны квадранты 1 и 2;
автомобилю, движущемуся на запад, нужны квадранты 2 и 3;
автомобилю, движущемуся на юг, нужны квадранты 3 и 4;
автомобилю, движущемуся на восток, нужны квадранты 4 и 1.
Обычное правило пересечения перекрестка состоит в том, что автомобиль должен уступить дорогу движущемуся справа. Это правило работает, когда перекресток пересекают два или три автомобиля. Например, если на перекрестке встретятся автомобили, движущиеся на север и на запад, то автомобиль, движущийся на север, уступит дорогу автомобилю, движущемуся на запад. Но если перекресток пересекают одновременно четыре автомобиля, каждый из которых согласно правилу воздержится от въезда на перекресток, возникнет взаимоблокировка. Она возникнет и в том случае, если все четыре машины проигнорируют правило и осторожно въедут на перекресток, поскольку при этом каждый автомобиль захватит один ресурс (один квадрант) и останется на вечной стоянке в ожидании, когда другой автомобиль освободит следующий требующийся для пересечения перекрестка квадрант. Итак, мы опять получили взаимоблокировку.
1Дословно — "мертвые объятия". В русскоязычной литературе встречаются термины "тупик", "клинч", однако наиболее полно отражает суть происходящего именно термин "взаимоблокировка". — Прим, перев.
Рассмотрим теперь картину взаимоблокировки с участием процессов и системных ресурсов. На рис. 6.2 показано выполнение двух процессов, конкурирующих в борьбе за два ресурса. Каждый из процессов требует исключительного владения обоими ресурсами на некоторое время. Процессы Р и Q имеют общий вид:
Process Р Process Q
•
•
• Get A Get В
•
•
• Get В Get A
•
•
• Release A Release В
•
•
• Release В Release. A
•
•
•
На рис. 6.2. ось х представляет выполнение процесса Р, а ось у — выполнение процесса Q. Таким образом, совместное выполнение двух процессов можно представить в виде пути из начала координат в северо-восточном направлении. В однопроцессорной системе в каждый момент времени может выполняться только один процесс, так что путь состоит из чередующихся горизонтальных и вертикальных отрезков, причем горизонтальные отрезки представляют работу процесса Р, а вертикальные — процесса Q.
На рис. 6.2 показаны шесть различных путей выполнения процессов.
Q получает ресурс В, затем — ресурс А, затем освобождает ресурсы В и А. Когда процесс Р продолжает выполнение, он может получить оба ресурса.
Q получает ресурс В, а затем — ресурс А. Процесс Р начинает работу и блокируется при запросе ресурса A. Q освобождает ресурсы В и А. Когда процесс Р продолжает выполнение, он может получить оба ресурса.
Q получает ресурс В, затем Р получает ресурс А. Взаимоблокировка неизбежна, поскольку выполнение Q заблокируется при запросе ресурса А, а выполнение процесса Р — при запросе ресурса В.
Р получает ресурс А, затем Q получает ресурс В. Взаимоблокировка неизбежна, поскольку выполнение Q заблокируется при запросе ресурса А, а выполнение процесса Р — при запросе ресурса В.
Р получает ресурс А, а затем — ресурс В. Процесс Q начинает работу и блокируется при запросе ресурса В. Р освобождает ресурсы А и В. Когда процесс Q продолжает выполнение, он может получить оба ресурса.
Р получает ресурс А, затем — ресурс В, затем освобождает ресурсы А и В. Когда процесс Q продолжает выполнение, он может получить оба ресурса.
Произойдет взаимоблокировка или нет, зависит как от динамики выполнения процессов, так и от подробностей построения приложения. Предположим, например, что процесс Р не требует получения обоих ресурсов одновременно и имеет следующий вид:
Process Р
•
•
Get A
•
•
Release А
•
•
Get В
•
•
Release В
• /
•
•
Эта ситуация изображена на рис, 6.3. Немного поразмыслив, вы можете убедиться, что независимо от того, каким образом два процесса выполняются друг относительно друга, взаимоблокировка невозможна.