1. Решение:
I
Здесь не инициализированы семафоры B1
и B2, т.е. не известно, что
произойдет. А если эти семафоры
инициализировать B1:=1;B2:=0;,
то получим правильное решение задачи.
PP: procedure (var S: integer);
common binary semaphore B1, B2;
Begin P(B1); S:=S–1; if S<0 then begin V(B1); P(B2) end
Else V(B1) end;
VP: procedure (var S: integer);
common binary semaphore B1, B2;
Begin P(B1); S:=S+1; if S<=0 then V(B2); V(B1 ) end;
2. Решение:
Init: proc (var S: integer; value: integer);
Этот вариант зайдет в тупик на Р(В2); при
первом же вызове, т.к. В2=0 и никогда В2
не равно 1.
begin B1:=1; B2:=0; S:=value end;
PP: procedure (var S: integer);
common binary semaphore B1, B2;
Begin P(B1); S:=S–1; P(B2) end;
VP: procedure (var S: integer);
common binary semaphore B1, B2;
Begin P(B2); S:=S+1; V(B1 ) end;
3. Решение:
Init: proc (var S: integer; value: integer); common binary semaphore B;
begin B:=1; S:=value end;
PP: procedure (var S: integer); Здесь ошибка такая же как в 4 варианте 7 задания
common binary semaphore B;
Begin if S>0 then begin P(B); S:=S–1; V(B) end end;
VP: procedure (var S: integer);
common binary semaphore B;
Begin P(B); S:=S+1; V(B) end;
4
Во первых, не инициализированы В1 и В2.
Во вторых, при S<0 PP
не выходит из КС, из-за этого невозможно
даже освободить ресурс в VP,
т.е. тупик.
Init: proc (var S: integer; value: integer); begin S:=value end;
PP: procedure (var S: …); common binary semaphore B1, B2;
Begin P(B1); S:=S–1; if S<0 then P(B2) Else V(B1) end;
VP: procedure (var S: …); common binary semaphore B1, B2;
Begin P(B1); S:=S+1; if S<=0 then V(B2); V(B1 ) end;
5. Решение:
I
Здесь тоже при S<0 PP
не выходит из КС, из-за этого невозможно
освободить ресурс в VP,
т.е. тупик.
common binary semaphore B1, B2;
begin B1:=1; B2:=1; S:=value end;
PP: procedure (var S: integer);
common binary semaphore B1, B2;
Begin P(B1); S:=S–1; if S<0 then P(B2) Else V(B1) end;
VP: procedure (var S: integer);
common binary semaphore B1, B2;
Begin P(B1); S:=S+1; if S>0 then V(B2); V(B1 ) end;
Задание 9. Задача “обедающие философы” формулируется следующим образом: “Пять философов садятся обедать за круглый стол, в центре которого стоит одно блюдо со спагетти. На столе имеется пять тарелок и пять вилок между ними. Философ может начать есть, если у него есть тарелка и две вилки, которые он может взять с двух сторон от своей тарелки. Философ может отдать вилки соседям только после того, как он закончит обед”. О соображениях гигиены мы здесь умалчиваем. Может ли описанный ниже на псевдокоде процесс представить алгоритм поведения философа за столом (привести примеры, иллюстрирующие возможные проблемы)?
Решение:
Инициализация:
{ “Вилки”, которые используются философами – это разделяемые ресурсы, защищенные бинарными семафорами: }
common B: array[0..4] of binary semaphore; { глобальный массив семафоров}
for I:=0 to 4 do B[I]:=1; { все “вилки” свободны }
process Философ(I: Integer);
{ Это процесс, описывающий поведение I-го философа. }
{ “Вилки”, которыми он ест, защищаются двумя бинарными семафорами. }
common B: array[0..4] of binary semaphore
begin { Пытается получить вилки: }
while (P(B[I])=0) or (P(B[(I+1) mod 5])=0) do ;
{ Ест спагетти, используя вилки, находящиеся слева и справа } …
{ Освобождает вилки: } V(B[(I+1) mod 5]); V(B[I]);
end;
Довольно странное использование примитивов, но даже если синтаксис и семантика языка допускают такую конструкцию и Р выполняет те же действия, что и обычно, то возможен тупик. Если все философы одновременно будут проверять условия, то каждый может взять левую вилку, а когда будет проверять правую, обнаружит, что она занята и будет ждать ее освобождения, но она никогда не освободится, т.к. освобождение вилки может быть тогда, и только тогда, когда философ поест.