Implementacja monitora

Należy napisać odpowiedniki operacji monitorowych korzystając z semaforów:

  1. Rozpoczęcie wykonywania procedury.

  2. Zakończenie wykonywania procedury.

  3. Operacja wait.

  4. 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;