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

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;

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

 

 

Задача “производитель-потребитель”, буфер неограниченного размера

решение «спящий парикмахер»

 

Begin

Integer ЧПБ, РБ, ЗП;

ЧПБ:=0; РБ:=1; ЗП:=0;

Parbegin

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

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

P(РБ);

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

ЧПБ:=ЧПБ+1;

if (ЧПБ=0) then begin V(РБ); V(ЗП); end

Else V(РБ);

Goto n1;

End;

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

n2: P(РБ);

ЧПБ:=ЧПБ-1;

if (ЧПБ=-1) then begin V(РБ); P(ЗП); P(РБ); end;

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

V(РБ);

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

Goto n2;

End;

Parend;

 

 

Эта программа называется "спящий парикмахер"

Используется два двоичных семафора: работа с буфером и задержка потребителя.

Особенности:

- используются только двоичные семафоры;

- задача взаимного исключения реализуется через семафоры;

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

 

 

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