Добавление новой порции в буфер;
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;
Эта программа называется "спящий парикмахер"
Используется два двоичных семафора: работа с буфером и задержка потребителя.
Особенности:
- используются только двоичные семафоры;
- задача взаимного исключения реализуется через семафоры;
- через семафоры реализуется задержка потребителя, которая действует при попытке потребителя читать данные из пустого буфера.
Задача “производитель-потребитель”,