Parbegin

процесс 1: begin … end;

процесс 2: begin … end;

процесс N: begin … end;

parend;

end;

процесс i:

Begin

Li: P(свободно);

Критический интервал i;

V(свободно);

Остаток цикла i;

goto Li;

end;

Задача “производитель-потребитель”

Общие семафоры

Рассматриваются два процесса, которые называются производитель и потребитель. Оба процесса являются циклическими. Производитель при каждом циклическом повторении участка программы производит отдельную порцию информации, которая должна быть обработана потребителем. Потребитель при каждом повторении обрабатывает следующую порцию информации, выработанную производителем. Отношения производитель-потребитель подразумевают односторонний канал связи, по которому могут передаваться порции информации. С этой целью процессы связаны через буфер неограниченной емкости. То есть, произведенные порции не должны немедленно потребляться, а могут организовывать в буфере очередь. Буфер работает по принципу FIFO.

ЧПБ – число порций в буфере.

РБ – работа с буфером

begin integer ЧПБ;

ЧПБ:= 0;

Parbegin

Производитель: begin

П1: производство новой порции;

добавление новой порции в буфер;

V(ЧПБ);

goto П1;

end;

Потребитель: begin

П2: P(ЧПБ);

взятие порции из буфера;

обработка взятой порции;

goto П2;

end;

parend;

end;

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

begin integer ЧПБ, РБ;

ЧПБ:= 0;

Parbegin

Производитель: begin

П1: производство новой порции;

P(РБ)

добавление новой порции в буфер;

v(PБ);

v(ЧПБ);

goto П1;

end;

Потребитель: begin

П2: p(ЧПБ);

p(PБ);

взятие порции из буфера;

v(PБ);

обработка взятой порции;

goto П2;

end;

parend;

end;

При решении стремятся использовать только двоичные семафоры. В таком случае программа будет выглядеть так:

ЗП - задержка потребителя.

СЧПБ - счетчик порций в буфере.

begin integer ЧПБ, РБ, ЗП;

ЧПБ:= 0;

РБ:= 1;

ЗП:= 0;

Parbegin

Производитель: begin

П1: производство новой порции;

P(РБ)

добавление новой порции в буфер;

ЧПБ:= ЧПБ + 1;

If (ЧПБ = 1) then v(ЗП);

v(PБ);

goto П1;

end;

потребитель: begin integer СЧПБ;

ждать: p(ЗП);

продолжить: p(PБ);

взятие порции из буфера;

ЧПБ:= ЧПБ - 1;

СЧПБ:= ЧПБ;

v(PБ);

обработка взятой порции;

if (CЧПБ = 0) then goto ждать;

else goto продолжить;

end;

parend;

end;

Значение локальной переменной СЧПБ устанавливается при взятии порции из буфера и фиксируется, не была ли эта порция последней. Здесь двоичный семафор РБ решает задачу взаимного исключения при работе с буфером. Введен новый двоичный семафор – задержка потребителя (ЗП). Работа программы представляет интерес в течение времени, когда буфер пуст. В исходном состоянии семафор ЗП установлен в ноль и открывается производителем только в том случае, когда в пустой буфер записывается порция. Остановка потребителя на семафоре ЗП не блокирует работу с буфером, так как стоит выше операции р(РБ). Смысл ждать есть только в том случае, если буфер пуст.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: