Grupy Procesów

W systemiie N>1 grup procesów (liczność grup nie jest znana) korzysta z K>1 zasobów ponumerowanych od 1 do K. Każdy proces działa według schematu:

process P(grupa: 1..N);
var k: integer;
begin
 while true do
 begin
  wlasne_sprawy;
  SERWER.chce_korzystac(grupa, k);
  korzystam(k);
  SERWER.skonczylem(k);
 end;
end;

Zasady korzystania z zasobów są następujące:

Napisz monitor SERWER zarządzający dostępem do zasobów w taki sposób, aby powyższe warunki były spełnione i żaden proces nie został zagłodzony.

Rozwiązanie:

monitor SERWER;

type
 status_zasobu_t = (wolny, zajety)

var
 czeka_grupa: array [1..N] of condition;
 czeka_lider: condition;
 czy_czeka_lider: array [1..N] of boolean := N times false;
 czeka_na_zasob: array[1..K] of condition;
 status_zasobu: array[1..K] of status_zasobu_t := N times wolny;
 aktualna_grupa: integer;
 liczba_procesow_zatwierdzonych: integer := 0;

export procedure chce_korzystac(grupa: 1..N, zasob: 1..K)
begin
 if (liczba_procesow_zatwierdzonych=0) then
  aktualna_grupa := grupa;
 else if (grupa<>aktualna_grupa or not empty(czeka_lider)) then
  if (not czy_czeka_lider[grupa]) then
  begin
   czy_czeka_lider[grupa] := true;
   wait(czeka_lider);
   aktualna_grupa := grupa;
   czy_czeka_lider[grupa] := false;
  end;
  else
   wait(czeka_grupa[grupa]);

 liczba_procesow_zatwierdzonych++;

 signal(czeka_grupa[aktualna_grupa]); {:aktualna_grupa=grupa:}

 if (status_zasobu[zasob]=zajety)
  wait(czeka_na_zasob[zasob])
 status_zasobu[zasob]:=zajety;
end;

export procedure skonczylem(zasob: 1..K)
begin
 status_zasobu[zasob]:=wolny;
 signal(czeka_na_zasob[zasob]);
 liczba_procesow_zatwierdzonych--;
 if (liczba_procesow_zatwierdzonych=0) then
   signal(czeka_lider);
end;