Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ОСиС_2008

.pdf
Скачиваний:
96
Добавлен:
29.05.2015
Размер:
2.65 Mб
Скачать

2. Системная поддержка мультипрограммирования

89

90

Одиноков В.В., Коцубинский В.П.

2.5.2. Обыкновенные программные каналы

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

вкоторую с одной стороны один или несколько процессов направляют (записывают) последовательности байтов, а с другой — один или несколько процессов выбирают (считывают) последовательности байтов. Основные свойства канала:

1)последовательность байтов, помещаемых в канал одним процессом за одну операцию записи, не может быть перемешана с какой-то последовательностью байтов от другого процесса;

2)длины считываемых из канала последовательностей байтов никак не зависят от длин записываемых последовательностей байтов.

Более точное определение: канал — специальный файл, запись

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

Обыкновенный каналсоздаетсяврезультатесистемноговызова:

СОЗДАТЬ_КАНАЛ (|| i1, i2) (на СИ — pipe),

где i1 — программное имя (номер) файла, открытого для записи в канал; i2 — номер файла, открытого для чтения из канала.

Таким образом, один и тот же файл-канал оказывается открытым дважды и поэтому имеет два номера. Теперь процесс, выдавший данный вызов, может записывать в канал и считывать из него, пользуясь обычными системными вызовами для работы с файлами:

ЧТЕНИЕ_ФАЙЛА (i2 , Ab, nb ||) (на СИ — read),

ЗАПИСЬ_ФАЙЛ (i1 , Ab, nb ||) (на СИ — write),

где Ab — начальный адрес области ОП, в которую производится чтение из файла-канала или из которой производится запись в канал; nb — число читаемых (записываемых) байтов.

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

2. Системная поддержка мультипрограммирования

91

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

Операция чтения из канала может завершиться одним из следующих вариантов:

1)при чтении меньшего числа байтов, чем находится в канале, операция завершается успешно;

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

3)если канал пуст и не открыт на запись ни в одном из процессов, то в результате чтения из канала выдается 0 байтов. Если же канал открыт на запись хотя бы в одном процессе, системный вызов чтения будет заблокирован до появления в канале данных.

Операция записи в канал может завершиться одним из следующих вариантов:

1)при записи меньшего числа байтов, чем имеется свободного места в канале, операция завершается успешно;

2)при записи в канал большего числа байтов, чем имеется

внем свободного места, вызов ЗАПИСЬ_ФАЙЛ блокируется до освобождения требуемого места;

3)если процесс пытается выполнить запись в канал, не открытый ни одним процессом на чтение, то в этот процесс посылается сигнал SIGPIPE. По умолчанию сигнал SIGPIPE завершает процесс.

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

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

92

Одиноков В.В., Коцубинский В.П.

соединяются все процессы, команды запуска которых образуют конвейер, набираемый пользователем в командной строке shell (см. п. 1.5.3.). В данном случае каналы создает shell, дочерними процессами которого и являются процессы, образующие конвейер.

2.5.3. Именованные программные каналы

Если требуется обеспечить обмен информацией между «не родственными» процессами, то для этого можно использовать именованные каналы, которые реализованы не во всех UNIX- системах. Именованный канал имеет имя, аналогичное имени обычного файла. Это имя канал получает при своем создании в результате выполнения процессом системного вызова:

СОЗДАТЬ_ИМЕННОЙ_КАНАЛ (I, m||) (на СИ — mkfifo),

где I — символьное имя файла-канала; m — права доступа к каналу (рассматриваются в подразд. 3.2).

После создания канала он может быть открыт на чтение или на запись в любом числе процессов с помощью вызова:

ОТКРЫТЬ_ФАЙЛ(I, r|| i) (на СИ — open),

где r — режим работы процесса с файлом-каналом (чтение и (или) запись); i — программное имя (номер) файла, уникальное для данного процесса.

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

В отличие от обыкновенных каналов, именованные каналы «видны» для пользователя. С помощью команды shell mknod он может создавать новые именованные каналы, чтобы затем использовать их для связи между процессами. Для того чтобы затем подсоединить канал к процессу, достаточно перенаправить стандартный ввод (вывод) процесса на этот файл-канал.

Другие методы информационного взаимодействия между процессами будут рассмотрены нами в подразд. 4.6.

2.6. Тупики

2.6.1. Причины появления тупиков

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

P2
ВЫДАТЬ_РЕСУРС (T,…||…)
. . . . . . . . . . .

2. Системная поддержка мультипрограммирования

93

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

Пусть каждый из параллельных процессов P1 и P2 осуществляет операции записи в файл D, размещенный на магнитной ленте. В ВС имеется единственный стример (лентопротяжное устройство) T. Известно, что перед работой с файлом D P2 использует T для работы с другим файлом. Выполнение P1 и P2 во времени может иметь вид

P1

. . . . . . . . . . .

ВЫДАТЬ_РЕСУРС (D,…||…)

M1: ВЫДАТЬ_РЕСУРС (T,…||…) . . . . . . . . . . .

M2: ВЫДАТЬ_РЕСУРС (D,…||…)

В данном примере P2 сначала получил T, а затем P1 получил D. Далее P1 дошел до метки M1, а P2 достиг метки M2. Сразу же после достижения процессом P2 метки M2 оба процесса оказываются в тупике. При этом P1 будет заблокирован по T, сохраняя за собой D, тогда как P2 блокирован по D, сохраняя T. P1 не может продолжаться, если не продолжается P2, и наоборот. Таким образом, процессы сомкнулись «в смертельном объятии». Эту тупиковую ситуацию можно представить в виде графа (рис. 17).

D

P1

P2

Запрос T Распределение

Рис. 17. Процессы P1 и P2 находятся в тупике из-за ресурсов T и D

Следующий пример показывает возможность возникновения тупика из-за одного ресурса. Пусть повторно используемый ресурс R (например ОП или ВП) содержит m единиц и распределяется среди n процессов P1,…, Pn (2<m<n). Причем каждый процесс использует элементы ресурса R в последовательности

ВЫДАТЬ_РЕСУРС (R,…||…)

94

Одиноков В.В., Коцубинский В.П.

ВЫДАТЬ_РЕСУРС (R,…||…) ОСВОБОДИТЬ_РЕСУРС (R,…||…) ОСВОБОДИТЬ_РЕСУРС (R,…||…),

где каждая из записанных операций действует на единицу R. Когда распределены все единицы ресурса, легко может воз-

никнуть тупик, так как процессы, держащие по единице R, могут навсегда заблокироваться на второй операции ВЫДАТЬ_РЕСУРС. Некоторые процессы могут навсегда заблокироваться уже на первой единице. Возможный тупик при n = 3, m = 2 приведен на рис. 18.

R

P1 P2 P3

Рис. 18. Процессы P1, P2, P3 находятся в тупике из-за ресурса R

2.6.2. Методы предотвращения тупиков

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

коэффициент эффективности распределения ресурса — отно-

шение объема полезноиспользуемого ресурса к общему объему распределенного ресурса.

Рассмотрим простой метод предотвращения тупика на этапе запуска процесса. Данный метод, как и многие другие, использует количественную информацию о потребностях процессов в ресурсах, представленную в виде векторов ресурсов и матриц распределения ресурсов среди процессов. Каждый вектор ресурсов R имеет размерность m — число ресурсов, распределение которых может привести к возникновению тупиков. Сами эти ресурсы обозначим как r1,…, rm. Размер матрицы распределения T n x m, где n — число процессов, существующих в системе. Со

2. Системная поддержка мультипрограммирования

95

временем число n может изменяться. В данном методе используются один вектор ресурсов и одна матрица распределения:

1)Rобщ — вектор общего наличия ресурсов. Компонента вектора Rобщ i показывает, сколько всего единиц i-го ресурса распределяются в системе среди процессов;

2)Tнаиб — матрица наибольших требований процессов к ресурсам. Элемент матрицы Tнаиб ij показывает, какое наибольшее количество j-го ресурса может потребоваться i-му процессу. Строка

Tнаиб i содержит максимальные потребности i-го процесса во всех рассматриваемых ресурсах.

Сущность данного метода заключается в том, что новый (n+1)-й процесс запускается только в том случае, если выполняется условие

 

 

 

Rобщ

Tнаиб(n+1) +n

Tнаиб i

(*)

Пример

 

 

 

 

 

i=1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Исходное состояние системы имеет вид

 

 

 

 

 

r1

r2

 

r3

r4

 

 

 

 

 

 

 

Tнаиб = P1

7

2

 

4

3

Rобщ =

13

6

8

6

 

Допустим, что готовы к запуску процессы P2 и P3, имеющие следующие максимальные потребности в ресурсах:

 

 

r1

r2

 

r3

r4

 

 

r1

r2

r3

r4

Tнаиб 2 = P2

 

1

 

3

6

3

 

Tнаиб 3 = P3

4

2

1

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Для проверки возможности запуска P2 найдем сумму

 

 

Tнаиб + Tнаиб 2 =

 

 

8

 

5

 

10

6

 

 

 

 

 

Так как найденная сумма не отвечает условию (*), то процесс P2 запущен быть не может. Проверим теперь возможность запуска процесса P3:

Tнаиб + Tнаиб 3 =

11

4

5

6

 

 

 

 

 

Найденная сумма отвечает условию (*), и поэтому процесс P3 запускается. В результате этого состояние системы принимает вид

 

r1

r2

r3

r4

 

 

 

 

 

Tнаиб = P1

7

2

4

3

Rобщ =

13

6

8

6

P3

4

2

1

3

 

 

 

 

 

96

Одиноков В.В., Коцубинский В.П.

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

Простейший метод предотвращения тупиков на этапе выделения ресурсов заключается в том, что все требуемые ресурсы запрашиваются процессом сразу, в начале своего выполнения. Для того чтобы тупик не возник при этом в начале процесса, на множестве ресурсов ВС должен быть задан порядок, согласно которому ресурсы могут запрашиваться в процессах. Что касается дальнейшего хода процесса, то тупик в принципе невозможен, так как процесс больше не будет обращаться с просьбами выделения ресурсов. Освобождать свои ресурсы процесс может в произвольные моменты времени. Например, перепишем согласно этому методу программы процессов P1, P2 в примере, изображенном на рис. 17. В результате тупик больше не угрожает выполнению этих процессов:

P1 P2

ВЫДАТЬ_РЕСУРС (T,…||…) ВЫДАТЬ_РЕСУРС (D,…||…)

. . . . . . . . . . .

ОСВОБОДИТЬ_РЕСУРС (T,…||…) ОСВОБОДИТЬ_РЕСУРС (D,…||…) . . . . . . . . . . .

. . . . . . . . . . . ВЫДАТЬ_РЕСУРС (T,…||…) ВЫДАТЬ_РЕСУРС (D,…||…)

. . . . . . . . . . .

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

2. Системная поддержка мультипрограммирования

97

Второй метод безтупикового распределения ресурсов использует следующую количественную информацию:

1)Rобщ — вектор общего наличия ресурсов;

2)Rсвоб — вектор свободных ресурсов. Компонент вектора Rсвоб i показывает, сколько единиц i-го ресурса в данный момент времени свободны;

3)Tнаиб — матрица наибольших требований процессов к ресур-

сам;

4)Tрас — матрица распределения ресурсов между процессами. Элемент матрицы Tрас ij показывает, какое количество j-го ресурса на данный момент времени распределено i-му процессу. Строка

Tрас i содержит объемы всех рассматриваемых ресурсов, полученные i-м процессом.

Совокупность перечисленных векторов и матриц образует состояние системы. Данное состояние называется безопасным состоянием, если все находящиеся в системе процессы могут быть успешно завершены. При этом считается, что для завершения процесса ему необходимо предоставить те объемы ресурсов,

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

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

Пример

 

 

 

 

 

 

 

 

 

 

 

 

 

Пусть система находится в исходном состоянии:

 

 

 

Tнаиб = P1

 

r1

 

r2

 

r3

 

r4

Rобщ =

 

 

 

 

7

2

4

3

13

6

8

6

P2

1

3

6

3

 

 

 

 

 

P3

4

2

1

3

 

 

 

 

 

P4

7

3

0

2

 

 

 

 

 

Tрас = P1

 

r1

 

r2

 

r3

 

r4

Rсвоб =

 

 

 

 

 

3

 

1

 

2

 

1

2

1

2

3

98

 

 

 

Одиноков В.В., Коцубинский В.П.

P2

 

 

 

 

 

1

1

4

1

 

P3

2

1

0

1

 

P4

5

2

0

0

 

Пусть процесс P2 сделал дополнительный запрос на 1 единицу ресурса r4. Тогда новое состояние системы будет следующим:

Tнаиб = P1

r1

r2

r3

r4

Rобщ =

 

 

 

 

 

 

 

 

 

 

7

2

4

3

13

 

 

6

 

 

8

 

6

 

P2

1

3

6

3

 

 

 

 

 

 

 

 

 

 

 

P3

4

2

1

3

 

 

 

 

 

 

 

 

 

 

 

P4

7

3

0

2

 

 

 

 

 

 

 

 

 

 

 

Tрас = P1

r1

r2

r3

r4

Rсвоб =

 

 

 

 

 

 

 

 

 

 

3

1

2

1

2

1

 

2

 

2

 

P2

1

1

4

2

 

 

 

 

 

 

 

 

 

 

 

P3

2

1

0

1

 

 

 

 

 

 

 

 

 

 

 

P4

5

2

0

0

 

 

 

 

 

 

 

 

 

 

 

Для проверки безопасности этого состояния попробуем завершить какой-нибудь процесс, исходя из его максимальных потребностей в ресурсах. Это можно сделать для P3, так как выполняется

условие Tнаиб 3 Tрас 3 < Rсвоб. В результате завершения P3 система окажется в новом состоянии:

Tнаиб = P1

7

2

4

3

Rобщ =

13

6

8

6

P2

1

3

6

3

 

 

 

 

 

P4

7

3

0

2

 

 

 

 

 

 

r1

r2

r3

r4

 

 

 

 

 

Tрас = P1

3

1

2

1

Rсвоб =

4

2

2

3

P2

 

 

 

 

 

 

 

 

 

1

1

4

2

 

 

 

 

 

P4

5

2

0

0

 

 

 

 

 

Нетрудно убедиться, что далее процессы P1, P2, P4 могут быть завершены в любой последовательности и, следовательно, исходное состояние системы является безопасным.

Если видоизменить задачу так, что P2 запрашивает не одну, а две единицы ресурса r4, то, повторив изложенные рассуждения, нетрудно убедиться, что новое состояние системы будет опасным, и поэтому процесс P2 должен быть заблокирован.