W systemie dostępnych jest M zasobów. W systemie działa N procesów. Każdy proces działa według schematu:
wykonuje własne_sprawy
wyznacza zasoby, które są mu potrzebne
rezerwuje zasoby
pracuje korzystając z zasobów
zwalnia zasoby
Zapisz procedury rezerwowania i zwalniania zasobów:
Zapisz treść procesu P(j: 1..N) używając do synchronizacji semaforów.
Zapisz treść procesu P(j: 1..N) i monitor Serwer synchronizujący dostęp do zasobów.
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;
Rezerwacja grupy zasobów musi być przeprowadzona w określony sposób. Rozważmy sytuację gdy proces A chce zarezerwać zasób X a potem zasób Y, a proces B chce zarezerwować zasób Y a potem zasób X. Jeśli proces A zarezerwuje zasób X, proces B zarezerwuje zasób Y to proces A będzie czekał na zwolenienie zasobu Y a proces B będzie czekał na zwolnienie zasobu X. Taka sytuacja to zakleszczenie. Można uniknąć zakleszczenie, jeśli zasoby rezerwowane są w tej samej kolejności (np od najmniejszego do największego) - dlatego w rozwiązaniach najpierw sortujemy identyfikatory zasobów.
var
rezerwacja_zasobu: array[1..M] of binary_semaphore := (M times 1);
procedure rezerwuj_zasoby(potrzebne_zasoby: array[1..K] of (1..M))
var i: integer;
zasob: (1..M);
begin
sort(potrzebne_zasoby);
for i:=1 to K do
begin
zasob := potrzebne_zasoby[i];
P(rezerwacja_zasobu[zasob]);
end;
end;
procedure zwolnij_zasoby(potrzebne_zasoby: array[1..K] of (1..M))
var i: integer;
zasob: (1..M);
begin
sort(potrzebne_zasoby);
for i:=1 to K do
begin
zasob := potrzebne_zasoby[i];
V(rezerwacja_zasobu[zasob]);
end;
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;