Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 7.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
196.61 Кб
Скачать

Лекция 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.

если скорости процессов произвольные, то может возникнуть ситуация, когда оба процесса получают возможность выполнять свои критические участки одновременно.