
- •5. Взаимодействие и синхронизация процессов
- •5.1. Взаимодействие процессов (Лекция 9)
- •5.1.1. Способы взаимодействия процессов
- •5.1.1.1. Проблема синхронизации
- •5.1.1.2. Критические секции, средства коммуникации процессов
- •5.1.1.3. Способы взаимодействия процессов, понятия взаимного исключения, взаимной блокировки, голодания процессов
- •5.1.2. Взаимные исключения
- •5.1.2.1. Требования к взаимным исключениям
- •5.1.2.2. Алгоритмы Деккера и Петерсона реализации взаимного исключения
- •5.2. Семафоры и другие средства синхронизации (Лекция 10)
- •5.2.1. Синхронизация задач с помощью семафоров
- •5.2.1.1. Семафоры Дейкстры
- •5.2.1.2. Условная синхронизация с помощью семафоров
- •5.2.1.3. Планирование очереди процессов, ожидающих у семафора
- •5.2.2. Другие средства синхронизации: счётчики событий, секвенсоры, мониторы, передача сообщений
- •5.2.2.1. Счетчики событий и секвенсоры
- •5.2.2.2. Объекты синхронизации, регламентированные posix
- •5.2.2.3. Мониторы Хоара
- •5.2.2.4. Передача сообщений
- •5.3. Классические проблемы межпроцессного взаимодействия (Лекция 11)
- •5.3.1. Проблема "обедающих философов"
- •5.3.1.1. Описание проблемы "обедающих философов"
- •5.3.1.2. Решение (алгоритм) проблемы "обедающих философов"
- •5.3.2. Проблема "спящего брадобрея" (задача о парикмахерской)
- •5.3.2.1. Описание задачи о парикмахерской
- •5.3.2.2. Решение (алгоритм) задачи о парикмахерской
- •5.3.3. Задача "читателей и писателей"
- •5.3.3.1. Описание задачи читателей и писателей
- •5.3.3.2. Решение (алгоритм) задачи читателей и писателей
- •5.4. Взаимоблокировки (Лекция 12)
- •5.4.1. Возникновение взаимоблокировок
- •5.4.1.1. Проблема взаимоблокировок
- •5.4.2. Устранение взаимоблокировок
- •5.4.2.1. Запрещение запуска процесса
- •5.4.2.2. Запрет выделения ресурса
- •5.4.3. Обнаружение взаимоблокировок
- •5.4.3.1. Алгоритм обнаружения взаимоблокировок
- •5.4.3.2. Действия, выполняемые после обнаружения взаимоблокировки
5.2.2.3. Мониторы Хоара
Для того, чтобы облегчить написание корректных программ, было предложено высокоуровневое средство синхронизации, называемое монитором. Монитор - это набор процедур, переменных и структур данных. Основными характеристиками монитора являются:
Локальные переменные монитора доступны только его процедурам; внешние процедуры доступа к локальным данным монитора не имеют;
Процесс входит в монитор путем вызова одной из его процедур;
В мониторе в определенный момент времени может выполняться только один процесс.
Компилятор обрабатывает вызовы процедур монитора особым образом. Обычно, когда процесс вызывает процедуру монитора, то первые несколько инструкций этой процедуры проверяют, не активен ли какой-либо другой процесс по отношению к этому монитору. Если да, то вызывающий процесс приостанавливается, пока другой процесс не освободит монитор. Таким образом, исключение входа нескольких процессов в монитор реализуется не программистом, а компилятором, что делает ошибки менее вероятными.
Монитор поддерживает синхронизацию при помощи переменных условия, располагающихся и доступных только в мониторе. Работать с этими переменными могут две функции:
Cwait(c) – приостанавливает выполнение вызывающего процесса по условию с. Монитор при этом доступен для использования другим процессом.
Csignal(c) – возобновляет выполнение некоторого процесса, приостановленного вызовом cwait с тем же условием. Если имеется несколько таких процессов, выбирается один из них; если таких процессов нет, функция не делает ничего.
В распределенных системах, состоящих из нескольких процессоров, каждый из которых имеет собственную оперативную память, семафоры и мониторы оказываются непригодными. В таких системах синхронизация может быть реализована только с помощью обмена сообщениями.
5.2.2.4. Передача сообщений
Еще один механизм – передача сообщений. Обычно функция передачи сообщений представляется в виде пары примитивов send(получатель, сообщение) иreceive(отправитель, сообщение). Однако при разработке систем передачи сообщений существует ряд вопросов:
Отправление: блокирующее/неблокирующее;
Получение: блокирующее/неблокирующее/проверка наличия;
Адресация: прямая (отправление, получение [неявное, явное]), косвенная (статическая, динамическая, владение)
Формат: Содержимое, длина (фиксированная, переменная)
Принцип работы очереди: FIFO, приоритетная.
5.3. Классические проблемы межпроцессного взаимодействия (Лекция 11)
5.3.1. Проблема "обедающих философов"
5.3.1.1. Описание проблемы "обедающих философов"
Классическая проблема, сформулированная Дейкстрой в 1965 г.
5 философов проводят свою жизнь за размышлениями и едой. На столе стоит кастрюля со спагетти, у каждого философа есть тарелка (рис. 6). Между каждыми тарелками лежит одна вилка.
Рис.6
Собственно, проблема в том, что спагетти очень скользкие, и философу нужно две вилки, чтобы с ними управиться. Получив две вилки одновременно, философ ест, затем кладет вилки на стол (и размышляет).
Если хотя бы одна из вилок рядом с тарелкой занята, философ ждет.
Требуется написать алгоритм, моделирующий поведение философа так, чтобы при параллельном исполнении не возникало тупиков.
Начинать решение удобно с анализа таких ситуаций, когда возникает тупик. Например, если каждый философ одновременно возьмет левую (или правую) вилку, то никому не достанется правой.
Выход из положения: после захвата одной вилки проверить доступность правой. Если она недоступна, положить взятую вилку и подождать. Но это тоже неправильно: при одновременном захвате одной вилки все процессы будут вынуждены одновременно вернуть вилку на стол; подождав одинаковое количество времени, они опять одновременно повторят те же действия, и процессы зависнут.
Очевидно, что нельзя ждать одинаковое время; правильное решение – случайное ожидание. Тогда процессы зависнут только в том случае, если случайно выпадут одинаковые времена ожидания; вероятность этого низка. Такое решение применяется в сети Ethernet: если две станции посылают пакеты одновременно, возникает коллизия, и по протоколу каждая станция должна подождать случайное время, а потом повторить попытку. Это обычно хорошо работает. Однако, можно решить задачу без случайных чисел. Одно из решений неэффективное, но верное: защитить доступ к вилкам (и к еде вообще) мьютексом. Но тогда в каждый момент времени сможет есть только один философ. А из рис.1 видно, что одновременно могут есть 2.