ПАРАЛЛЕЛЬНОЕ ПРОГРАММИРОВАНИЕ
28
Введем два семафора:
e
- число пустых буферов и
f
- число заполненных бу-
феров. Предположим, что запись в буфер и считывание из них являются критиче-
скими секциями (как в примере с принт-сервером). Введем также двоичный семафор
b
, используемый для обеспечения взаимного исключения. Тогда процессы могут
быть описаны следующим образом:
// Глобальные переменные
#define N 256
int e = N, f = 0, b = 1;
void Writer ()
{
while(1)
{
repareNextRecord(); /* подготовка новой записи */
P(e); /* Уменьшить число свободных буферов, если они есть */
/* в противном случае - ждать, пока они освободятся */
P(b); /* Вход в критическую секцию */
AddToBuffer(); /* Добавить новую запись в буфер */
V(b); /* Выход из критической секции */
V(f); /* Увеличить число занятых буферов */
}
void Reader ()
{
while(1)
{
P(f); /* Уменьшить число занятых буферов, если они есть */
/* в противном случае ждать, пока они появятся */
P(b); /* Вход в критическую секцию */
GetFromBuffer(); /* Взять запись из буфера */
V(b); /* Выход из критической секции */
V(e); /* Увеличить число свободных буферов */
ProcessRecord(); /* Обработать запись */
}
Достоинства:
пассивное ожидание (постановка в очередь и автоматическая выдача ресур-
сов);
возможность управления группой однородных ресурсов.
Недостаток: неправильное либо умышленное использование операций на
семафоре допускает нарушение работоспособности параллельных систем.
Действительно, если в рассмотренном примере переставить местами операции
P(e)
и
P(b)
в программе "писателе", то при некотором стечении обстоятельств эти
два процесса могут взаимно заблокировать друг друга. Так, пусть "писатель" пер-
вым войдет в критическую секцию и обнаружит отсутствие свободных буферов;
1...,20,21,22,23,24,25,26,27,28,29 31,32,33,34,35,36,37,38,39,40,...180