Zasoby

W systemie są dwie grupy procesów korzystających z N zasobów typu A i M zasobów typu B (N+M>1). Procesy z pierwszej grupy cyklicznie wykonują własne sprawy, po czym wywołują procedurę zamień_ab, która konsumuje jeden zasób A i produkuje jeden zasób B. Procesy z grupy drugiej cyklicznie wykonują własne sprawy, po czym wywołują procedurę zamień, która konsumuje jeden zasób dowolnego typu i produkuje zasób przeciwny.

type
zasob_t = (A,B);

process ZamieniajacyAB
var
  zasob: zasob_t;
  zasob_wyprodukowany: zasob_t;
begin
  while (true) do
  begin
    wlasne_sprawy();
    Zasoby.chce_zasob_a(zasob);
    zasob_wyprodukowany := zamien_ab(zasob);
    Zasoby.zwalniam(zasob_wyprodukowany);
  end;
end;

process Zamieniajacy
var
  zasob: zasob_t;
  zasob_wyprodukowany: zasob_t;
begin
  while (true) do
  begin
    wlasne_sprawy();
    Zasoby.chce_zasob(zasob);
    zasob_wyprodukowany := zamien(zasob);
    Zasoby.zwalniam(zasob_wyprodukowany);
  end;
end;

Zsynchronizuj procesy za pomocą monitora tak, żeby:

Rozwiązanie:

monitor Zasoby;

const:
  N = ...
  M = ...

var:
  ile_a := N; 
  ile_b := M;
  ile_procesow_ab := 0; 
  chce_a: condition;
  chce: condition;
  liczba_gotowych_z_pary := 0;

export procedure chce_zasob_a(var zasob: zasob_t)
begin
  if (ile_a<=1 or ile_procesow_ab=0) then
  begin
    inc(ile_procesow_ab);
    wait(chce_a);
    dec(ile_procesow_ab);
  end;
  zasob := pobierz_A();
  dec(ile_a);
  inc(liczba_gotowych_z_pary);
  if (liczba_gotowych_z_pary<2)
    signal(chce_a);
  else
    liczba_gotowych_z_pary:=0;
end;

export procedure chce_zasob(var zasob: zasob_t)
begin
  if (ile_b=0 and (ile_a=0 or (ile_a=1 and ile_procesow_ab>1))) then
    wait(chce);
  if (ile_b>0)
    zasob := pobierz_B();
    dec(ile_b);
  else
    zasob := pobierz_A();  
    dec(ile_a);
end;

export procedure zwalniam(zasob: zasob_t)
begin
  if (zasob=A)
  begin
    inc(ile_a);
    if (ile_procesow_ab<=1) then
      signal(chce);
    else if (ile_a>1) then
    begin
      signal(chce_a);
    end;
  end;
  else
  begin
   inc(ile_b);
   signal(chce);
  end;
end;