W systemie 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; var partner: 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:
Procesy różnych grup nie mogą korzystać jednocześnie z zasobów.
Z danego zasobu w danej chwili może korzystać tylko jeden proces.
Należy zadbać o efektywność rozwiązania - kiedy z zasobów zaczyna korzystać kolejna grupa, należy wykorzystać tyle zasobów, ile to możliwe.
Rozwiązanie:
monitor SERWER; czeka_pierwszy: condition; czeka_grupa: array [1..N] of condition; liczba_czekajacych_w_grupie: array [1..N] of integer; czeka_na_zasob: array [1..K] of condition; zasob_zajety: array [1..K] of 0..1 := {K TIMES 0}; grupa_korzystajaca: integer := -1; ilu_korzysta: integer := 0; export procedure chce_korzystac(grupa: 1..N, k: 1..K) begin if (grupa_korzystajaca == -1) then grupa_korzystajaca := grupa; if (not empty(czeka_pierwszy) || grupa_korzystajaca <> grupa) then begin ++liczba_czkejacych_w_grupie[grupa]; if (liczba_czekajacych_w_grupie[grupa] == 1) then begin wait(czeka_pierwszy); grupa_korzystajaca := grupa; end; else begin wait(czeka_grupa[grupa]); end; --liczba_czkejacych_w_grupie[grupa]; end; ilu_korzysta++; signal(czeka_grupa[grupa]); if (zasob_zajety[k]) wait(czeka_na_zasob[k]); zasob_zajety[k] := 1; end; export procedure skonczylem(k: 1..K) begin zasob_zajety[k] := 0; signal(czeka_na_zasob[k]); ilu_korzysta--; if (ilu_korzysta == 0) then begin grupa_korzystajaca := -1; signal(czeka_pierwszy); end; end;