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;