- •Лекция 7. Синхронизация параллельных процессов. Параллельная обработка
- •Проблемы критических участков. Взаимоисключения
- •Синхронизация в qnx
- •Синхронизация параллельных процессов на низком уровне Блокировка памяти
- •Алгоритм Деккера (Dekker’s Algorithm)
- •Аппаратная реализация взаимоисключения: команда “проверка и установка” (testandset)
- •Аппаратная реализация синхронизации
- •Инструкция "обменять содержимое переменных"
- •Семафоры
- •Синхронизация блокирования/возобновления процессов при помощи семафоров
- •Реализация взаимодействия в паре “производитель-потребитель” при помощи семафоров
- •Мониторы
- •Команды Wait () и Signal ().
- •Монитор, реализующий двоичный семафор.
- •Решение задачи передачи данных одного процесса другому при помощи монитора (случай кольцевого буфера)
- •Решение задачи передачи данных одного процесса другому при помощи монитора (случай информационной базы)
- •Службы синхронизации
- •Блокировки взаимного исключения (мьютексы)
- •Наследование приоритетов
- •Условные переменные
- •Барьеры
- •Ждущие блокировки
- •Блокировки по чтению/записи
- •Семафоры
- •Синхронизация с помощью алгоритма планирования
- •Синхронизация с помощью механизма обмена сообщениями
- •Синхронизация с помощью атомарных операций
- •Реализация служб синхронизации
Лекция 7. Синхронизация параллельных процессов. Параллельная обработка
Параллельными называются процессы, которые существуют одновременно. Параллельные процессы могут быть независимыми друг от друга или асинхронными. Асинхронным параллельным процессам требуется периодически синхронизироваться и взаимодействовать друг с другом.
Если определенные операции логически можно выполнять параллельно, то для указания параллелизма воспользуемся парой операторов parbegin/parend, которые будут, соответственно, определять начало и конец параллельного выполнения. Конструкция для указания параллелизма будет выглядеть следующим образом:
Parbegin
оператор_1;
оператор_2;
…
оператор_n
Parend
Если в определенный момент времени в системе существует более одного потока, то говорят, что потоки параллельны.
Взаимоисключения (mutual exclusion) – когда каждый поток, обращающийся к разделяемым данным (данные используемые в один и тот же момент времени), исключает для всех других потоков возможность одновременного с ним обращения к этим данным.
Проблемы критических участков. Взаимоисключения
Кретический ресурс - ресурс, который допускает обслуживание только одного пользователя за один раз. Если несколько процессов хотят пользоваться критическим ресурсом в режиме разделения времени, им следует синхронизировать свои действия таким образом, чтобы этот ресурс всегда находился в распоряжении не более чем одного их них.
Для каждого процесса могут быть выделены участки, в которых происходит обращение к критическим ресурсам, они называются критическими участками.
Пример:
Пусть два процесса X и Y разделяют переменную счет. Если оба процесса попытаются увеличить счет на 1 одновременно, то окончательное значение этой переменной может оказаться неверным. Рассмотрим следующую последовательность событий:
процесс X запоминает значение переменной счет в некоторой локальной переменной счет_Х;
процесс Y запоминает значение переменной счет в некоторой локальной переменной счет_Y;
процесс Х увеличивает значение счет_Х на 1 и записывает его в счет;
процесс Y увеличивает значение счет_Y на 1 и записывает его в счет.
Заметим, что хотя каждый процесс увеличил значение счет на 1, ее окончательное значение увеличилось только на 1, а не на 2. Чтобы избежать таких нежелательных явлений, увеличение разделяемой переменной счет следует рассматривать как критический участок.
Синхронизация в qnx
Отрывок программного кода, который должен выполняться "последовательно" (serially), т. е. не более чем одним потоком одновременно, называется "критической секцией программного кода" (critical section).
Синхронизация параллельных процессов на низком уровне Блокировка памяти
Взаимоисключения могут быть реализованы аппаратно, если сделать операции над памятью неделимыми. То есть, если каждый из процессов пытается поместить какие-либо значения в одну и ту же ячейку, то спор разрешается аппаратурой: если одному процессу разрешается выполнить операцию засылки немедленно, то другому приходится ждать пока первый не закончит операцию - такое разрешение спора и называется блокировкой памяти( storage interlock).
Попытаемся решить проблему критического участка для двух процессов X и Y с помощью некоторой переменной ключ, которая будет принимать значение true, когда процесс находится в своем критическом участке, и значение false - в противном случае. Прежде, чем войти в критический участок, процесс X проверяет ключ_Y другого процесса, чтобы убедится, что можно войти безопасно. Затем он включает свой собственный ключ_X и пользуется критическим участком.
var ключ_X, ключ_Y: boolean;
procedure процесс_Х;
begin
while (true) do
begin
while (ключ_Y) do;{ожидание, пока процесс Y не выйдет из критического участки}
ключ_X:=true;
{Критический участок Х}
ключ_X:=false;{признак выхода процесса X из критического участка}
{Оставшаяся часть процесса Х}
end;
end;
procedure процесс_Y;
begin
while (true) do
begin
while (ключ_X) do;{ожидание пока процесс X не выйдет из критического участка}
ключ_Y:=true;
{Критический участок Y}
ключ_Y:=false;{признак выхода процесса Y из критического участка}
{Оставшаяся часть процесса Y}
end;
end;
begin
ключ_X:=false;
ключ_Y:=false;
Parbegin
процесс_Х;
процесс_Y
Parend
end.
если скорости процессов произвольные, то может возникнуть ситуация, когда оба процесса получают возможность выполнять свои критические участки одновременно.
