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;