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;