Należy napisać odpowiedniki operacji monitorowych korzystając z semaforów:
Rozpoczęcie wykonywania procedury.
Zakończenie wykonywania procedury.
Operacja wait.
Operacja signal.
Rozwiązanie:
ochrona: binary semaphore := 1; stos: binary_semaphore := 0; ile_stos: integer :=0; warunek: binary_semaphore := 0; ile_warunek: integer := 0; procedure wejscie() begin P(ochrona); end; proceure wyjscie() begin if (ile_stos>0) then V(stos); else V(ochrona); end; procedure wait(var warunek: binary_semaphore, var ile_warunek: integer) begin inc(ile_warunek); if (ile_stos>0) then V(stos); else V(ochrona); P(warunek); dec(ile_warunek); end; procedure signal(var warunek: binary semaphore, ile_warunek: integer) begin if (ile_warunek>0) then begin inc(ile_stos); V(warunek); P(stos); dec(ile_stos); end; end;
Korzystając z tej implementacji, rozwiązanie problemu Grupy zasobów jest zapisane podobnie do rozwiązania monitorowego. W tym rozwiązaniu nie jest wykorzystany monitor (nie występują zmienne typu condition), ale wykorzystane są wyłącznie semafory.
ochrona: binary semaphore := 1; stos: binary semaphore := 0; ile_stos: integer := 0; czekanie_na_zasob: array[1..M] of binary semaphore := {M times 0}; ile_czeka_na_zasob: array[1..M] of integer := (M times 0); zasob_wolny: array[1..M] of (true,false) := (M times true); procedure rezerwuj_zasoby(potrzebne_zasoby: array[1..K] of (1..M)) var i: integer; zasob: (1..M); begin wejscie(); sort(potrzebne_zasoby); for i:=1 to K do begin zasob := potrzebne_zasoby[i]; if (zasob_wolny[zasob]=false) wait(czekanie_na_zasob[zasob], ile_czeka_na_zasob[zasob]); zasob_wolny[zasob]:=false; end; wyjscie(); end; procedure zwolnij_zasoby(potrzebne_zasoby: array[1..K] of (1..M)) var i: integer; zasob: (1..M); begin wejscie(); sort(potrzebne_zasoby); for i:=1 to K do begin zasob := potrzebne_zasoby[i]; zasob_wolny[zasob] := true; signal(czekanie_na_zasob[zasob], ilu_czeka_na_zasob[zasob]); end; wyjscie(); end; process P var potrzebne_zasoby: array of (1..M); begin while (true) do begin wlasne_sprawy(); potrzebne_zasoby := wyznacz_potrzebne_zasoby(); rezerwuj_zasoby(potrzebne_zasoby); pracuj(potrzebne_zasoby); zwolnij_zasoby(potrzebne_zasoby); end; end;