W systemie są dwie grupy procesów korzystających z N zasobów typu A i M zasobów typu B (N+M>1). Procesy z pierwszej grupy cyklicznie wykonują własne sprawy, po czym wywołują procedurę zamień_ab, która konsumuje jeden zasób A i produkuje jeden zasób B. Procesy z grupy drugiej cyklicznie wykonują własne sprawy, po czym wywołują procedurę zamień, która konsumuje jeden zasób dowolnego typu i produkuje zasób przeciwny.
type
zasob_t = (A,B);
process ZamieniajacyAB
var
zasob: zasob_t;
zasob_wyprodukowany: zasob_t;
begin
while (true) do
begin
wlasne_sprawy();
Zasoby.chce_zasob_a(zasob);
zasob_wyprodukowany := zamien_ab(zasob);
Zasoby.zwalniam(zasob_wyprodukowany);
end;
end;
process Zamieniajacy
var
zasob: zasob_t;
zasob_wyprodukowany: zasob_t;
begin
while (true) do
begin
wlasne_sprawy();
Zasoby.chce_zasob(zasob);
zasob_wyprodukowany := zamien(zasob);
Zasoby.zwalniam(zasob_wyprodukowany);
end;
end;
Zsynchronizuj procesy za pomocą monitora tak, żeby:
Procedury zamien_ab i zamien były wywoływane przez procesy jedynie pod warunkiem dostępności odpowiednich zasobów.
Procesy z grupy pierwszej wykonywały procedurę zamien_ab parami, tzn. proces z grupy pierwszej może rozpocząc jej wykonywanie jedynie wtedy, gdy jest inny proces z grupy pierwszej, gotowy do jej wykonania (i oczywiście niezbędne zasoby).
jednocześnie mogło odbywać się wiele operacji na zasobach, ale nie doszło do zagłodzenia żadnej grupy procesów.
Rozwiązanie:
monitor Zasoby;
const:
N = ...
M = ...
var:
ile_a := N;
ile_b := M;
ile_procesow_ab := 0;
chce_a: condition;
chce: condition;
liczba_gotowych_z_pary := 0;
export procedure chce_zasob_a(var zasob: zasob_t)
begin
if (ile_a<=1 or ile_procesow_ab=0) then
begin
inc(ile_procesow_ab);
wait(chce_a);
dec(ile_procesow_ab);
end;
zasob := pobierz_A();
dec(ile_a);
inc(liczba_gotowych_z_pary);
if (liczba_gotowych_z_pary<2)
signal(chce_a);
else
liczba_gotowych_z_pary:=0;
end;
export procedure chce_zasob(var zasob: zasob_t)
begin
if (ile_b=0 and (ile_a=0 or (ile_a=1 and ile_procesow_ab>1))) then
wait(chce);
if (ile_b>0)
zasob := pobierz_B();
dec(ile_b);
else
zasob := pobierz_A();
dec(ile_a);
end;
export procedure zwalniam(zasob: zasob_t)
begin
if (zasob=A)
begin
inc(ile_a);
if (ile_procesow_ab<=1) then
signal(chce);
else if (ile_a>1) then
begin
signal(chce_a);
end;
end;
else
begin
inc(ile_b);
signal(chce);
end;
end;