- •Лекція №9 Взаємоблокування
- •9.1. Принципы взаимного блокирования
- •9.2. Условия возникновения взаимоблокировок
- •9.3. Предотвращение, обнаружение и устранение взаимоблокировок
- •9.3.1. Игнорирование проблемы тупиков
- •9.3.2. Способы предотвращения тупиков
- •9.3.3. Обнаружение тупиков
- •9.3.4. Восстановление после тупиков
- •9.4. Механизмы параллельных вычислений в unix
- •9.4.1. Взаимодействие процессов
- •9.4.2. Разделяемая память
- •9.4.3. Семафоры
- •9.4.4. Очереди сообщений
- •9.4.5. Программные каналы
- •9.4.6. Программные гнезда (sockets)
Лекція №9 Взаємоблокування
Принципи взаємного блокування
Умови виникнення взаємоблокування
Запобігання, виявлення та усунення взаємо блокування
Ігнорування проблеми тупиків
Способи запобігання тупиків
Виявлення тупиків
Відновлення після тупиків
Механізми паралельних обчислень в UNIX
Взаємодія процесів
Колективна пам'ять
Семафори
Черги повідомлень
Програмні канали
Програмні гнізда (sockets)
9.1. Принципы взаимного блокирования
В компьютерных системах существует большое количество ресурсов, каждый из которых в конкретный момент времени может использоваться только одним процессом. Появление двух процессов, одновременно передающих данные, например, на принтер, приведет к печати бессмысленного набора символов. Наличие двух процессов, использующих один и тот же элемент таблицы файловой системы, станет причиной разрушения файловой системы. Поэтому все ОС обладают способностью предоставлять процессу эксклюзивный доступ не к одному, а к нескольким ресурсам.
Проиллюстрируем еще одну проблему синхронизации, когда могут возникнуть непредвиденные затруднения - взаимные блокировки, называемые также клинчами (clinch), дедлоками (deadlocks) или тупиками.
Рассмотрим пример тупика. Пусть двум потокам (процессам), выполняющимся в режиме мультипрограммирования, для выполнения их работы нужно два ресурса, например, порт и диск. На рисунке 9.1 (а) показаны фрагменты соответствующих программ. И пусть после того, как поток А занял порт (установил блокирующую переменную), он был прерван. Управление получил поток В, который сначала занял диск, но при выполнении следующей команды был заблокирован, так как порт оказался уже занятым потоком А. Управление снова получил поток А, который в соответствии со своей программой сделал попытку занять диск и был заблокирован: диск уже распределен потоку В. В таком положении потоки А и В могут находиться сколь угодно долго.
В зависимости от соотношения скоростей потоков, они могут либо совершенно независимо использовать разделяемые ресурсы (г), либо образовывать очереди к разделяемым ресурсам (в), либо взаимно блокировать друг друга (б).
В рассмотренных примерах тупик был образован двумя потоками, но взаимно блокировать друг друга могут и большее число потоков.
Тупики могут быть предотвращены на стадии написания программ, то есть программы должны быть написаны таким образом, чтобы тупик не мог возникнуть ни при каком соотношении взаимных скоростей потоков. Так, если бы в предыдущем примере поток А и поток В запрашивали ресурсы в одинаковой последовательности, то тупик был бы в принципе невозможен. Второй подход к предотвращению тупиков называется динамическим и заключается в использовании определенных правил при назначении ресурсов процессам, например, ресурсы могут выделяться в определенной последовательности, общей для всех процессов.
Существуют формальные, программно-реализованные методы распознавания тупиков, основанные на ведении таблиц распределения ресурсов и таблиц запросов к занятым ресурсам. Анализ этих таблиц позволяет обнаружить взаимные блокировки.
Рис. 9.1. Возникновение взаимных блокировок при выполнении программы; (б) взаимная блокировка (клинч); (в) очередь к разделяемому диску; (г) независимое использование ресурсов
В рассмотренном примере тупик был образован двумя потоками, но взаимно блокировать друг друга могут и большее число потоков.
Взаимоблокировки могут произойти во множестве других ситуаций помимо запросов выделенных устройств ввода-вывода. В системах баз данных программа может оказаться вынужденной заблокировать несколько записей, чтобы избежать состояния конкуренции. Если процесс А блокирует запись R1, процесс В блокирует запись R2, а затем каждый процесс пытается заблокировать чужую запись, мы также окажемся в тупике. Таким образом, взаимоблокировки появляются при работе как с аппаратными, так и с программными ресурсами.
Проблема тупиков включает в себя следующие задачи:
- предотвращение тупиков;
- распознавание тупиков;
- восстановление системы после тупиков.
Тупики могут быть предотвращены на стадии написания программ, то есть программы должны быть написаны таким образом, чтобы тупик не мог возникнуть ни при каком соотношении взаимных скоростей процессов. Так, если бы в предыдущем примере поток А и поток В запрашивали ресурсы в одинаковой последовательности, то тупик был бы в принципе невозможен. Второй подход к предотвращению тупиков называется динамическим и заключается в использовании определенных правил при назначении ресурсов процессам, например, ресурсы могут выделяться в определенной последовательности, общей для всех процессов.
В некоторых случаях, когда тупиковая ситуация образована многими процессами, использующими много ресурсов, распознавание тупика является нетривиальной задачей. Существуют формальные, программно-реализованные методы распознавания тупиков, основанные на ведении таблиц распределения ресурсов и таблиц запросов к занятым ресурсам. Анализ этих таблиц позволяет обнаружить взаимные блокировки.
Если же тупиковая ситуация возникла, то не обязательно снимать с выполнения все заблокированные процессы. Можно снять только часть из них, при этом освобождаются ресурсы, ожидаемые остальными процессами, можно вернуть некоторые процессы в область свопинга, можно совершить "откат" некоторых процессов до так называемой контрольной точки, в которой запоминается вся информация, необходимая для восстановления выполнения программы с данного места.