Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Операционные системы_лекции.doc
Скачиваний:
47
Добавлен:
28.09.2019
Размер:
1.71 Mб
Скачать

3.3. Управление параллельными процессами

3.3.1. Понятие параллельных процессов

В современных мультипрограммных системах могут одновременно выполняться несколько последовательных вычислительных процессов, находящихся в активном состоянии. Такие процессы называются параллельными и могут выполняться как на независимых устройствах, так и разделять различные ресурсы и конкурировать за них между собой. Например, может существовать конкуренция за процессорное время. Параллельные процессы могут быть независимыми и взаимодействующими.

Независимыми процессами называются процессы, которые не имеют общих данных, располагающихся в оперативной и внешней памяти. Независимые процессы не оказывают влияния друг на друга посредством изменения данных. Однако они замедляют исполнение друг друга.

Взаимодействующие процессы имеют общие данные, расположенные как в оперативной памяти, так и во внешней памяти. Они могут также конкурировать за разделяемые ресурсы. Разделяемые ресурсы, которые в каждый конкретный момент времени могут находиться в распоряжении только одного процесса, называются критическими. Два процесса, конкурирующие за критичес­кий ресурс должны быть синхронизированы, т.е. согласованы во времени. Это означает, что их обращения к критическим ресурсам должны происходить в разные моменты времени, в противном случае появляются ошибки, которые трудно выявляются и устраняются. Дополнительные трудности в синхронизацию параллельных процессов вносит разная скорость их исполнения, причём процессы не имеют информации ни о содержании, ни о скорости выполнения друг друга.

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

Обобщённая модель взаимодействующих процессов показана на рис. 3.2.

Рис. 3.2. Обобщённая модель взаимодействующих процессов

Коды процессов Р1 и Р2 имеют критические (CS1, CS2) и обычные (PR1, PR2) секции. Процессы Р1 и Р2 могут выполняться произвольное число раз, имеют общую область памяти Х и обращаются к критическому разделяемо­му ресурсу КР.

Формально описать взаимодействие процессов можно описать следующим программным кодом на языке, подобном Паскалю и Алголу 60 (рис. 3.3).

Begin

. . .

{начало программного кода}

Parbegin

{начало описания параллельных процессов}

S11; S12; . . . S1N

{список N операторов процесса № 1 }

AND

{разделитель описаний процессов }

S11; S12; . . . S1Q

{список Q операторов процесса № 2 }

Parend

{конец описания параллельных процессов}

End

{конец программного кода}

Рис. 3.3. Код, описывающий параллельные взаимодействующие процессы

По способу взаимного влияния взаимодействующие процессы можно разделить на конкурирующие и сотрудничающие. Конкурирующие процессы могут в принципе выполняться поодиночке. Однако при параллельном выполнении они начинают конкурировать за разделяемый критический ресурс и оказывать влияние друг на друга. Сотрудничающие процессы совместно обрабатывают общие данные и содержат в явном виде операторы передачи данных из одного процесса в другой.

В [1] описано несколько примеров конкурирующих процессов, в частности два не синхронизированных процесса Р1 и Р2, имеющих общую переменную Х, размещённую в оперативной памяти. Процесс Р1 имеет собственную переменную R1, а процесс Р2 – собственную переменную R2. Разумеется, эти переменные размещаются в памяти по разным адресам. Процесс Р1 состоит из трёх операторов присваивания: R1:=X, R1:=R1+1 и X:=R11. Процесс Р2 включает в себя тоже три оператора присваивания: R2:=X, R2:=R2+1 и X:=R2. Предположим, что к моменту начала выполнения процессов переменная Х имеет значение 10.

Пусть при выполнении процессов сложилась ситуация, в которой сначала выполнялся процесс Р1, а потом Р2. Тогда реализуется цепочка операторов, показанная в табл. 3.1. Ситуация, в которой после первого оператора процесса Р1 выполнится первый оператор процесса Р2 показана в табл. 3.2.

Таблица 3.1. Первый вариант взаимодействия конкурирующих процессов

Выполняемый оператор

Значения переменных

X

R1

R2

R1:=X

10

10

Не определена

R1:=X+1

10

11

Не определена

X:=R1

11

11

Не определена

R2:=X

11

11

11

R2:=R2+1

11

11

12

X:=R2

12

11

12

Таблица 3.2. Второй вариант взаимодействия конкурирующих процессов

Выполняемый оператор

Значения переменных

X

R1

R2

R1:=X

10

10

Не определена

R2:=X

10

10

10

R1:=X+1

10

11

10

X:=R1

11

11

10

R2:=R2+1

11

11

11

X:=R2

11

11

11

Из табл. 3.1 и 3.2 видно, что значения общей переменной Х в первом и втором вариантах получены разные. Очевидно, что хотя бы один из результатов является ошибочным. Вполне возможно, что ошибочными могут оказаться и оба результата выполнения подобных конкурирующих процессов. Для конкурирующих процессов введено понятие "взаимное исключение", означающее невозможность одновременного обращения двух и более процессов к критическому ресурсу.

Сотрудничающие процессы строятся по схеме "поставщик – потребитель". Для них так же, как и для конкурирующих процессов, справедлив механизм взаимных исключений, регулирующий доступ к критическим ресурсам. Однако, должны быть и средства синхронизации процессов, согласующих выполнение процессов во времени и позволяющие осуществить обмен данными. При обмене данными поставщик посылает потребителю сообщение. Однако потребитель может оказаться не готовым к принятию сообщения. Поэтому сообщение поступает в специально выделенную для обмена данными область памяти, называемую буфером, и ждёт выборки процессом-потребителем.

Однако, в силу разной скорости выполнения процессов и их разного содержания может возникнуть ситуация, в которой поставщик успевает послать несколько сообщений, прежде, чем потребитель выберет хотя бы одно. Для решения возникшей проблемы создаётся множество динамически распределяемых буферов, которое называется пулом буферов. Это приводит к появлению очереди буферов. Каждое новое сообщение создаёт буфер, который ставится в конец очереди.

В данном случае синхронизация процессов состоит в ведении обоими процессами совместного учёта занятых и свободных буферов и обеспечении чтения сообщений потребителем при непустой очереди и посылки сообщений поставщиком при наличии пустых буферов. Для ведения подобного учёта процессы должны иметь общие переменные, доступ к которым регулируется опять-таки на основе взаимных исключений.