Wielu klientów i wielu pracowników

Dodatkowe założenie: maksymalnie N zadań może być przetwarzanych jednocześnie.

Zauważmy, że w przypadku wielu pracowników przetwarzanie wewnątrz monitora prowadzi do ograniczenia wydajności. W monitorze może przebywać tylko jeden proces. Oznacza to, że zadania w tym przypadku będą przetwarzane pojedynczo. Z tego powodu rozwiązanie, w którym przetwarzanie odbywa się na zewnątrz monitora jest korzystniejsze.

type
status_t = (wolne, oczekujace, przetwarzane, gotowe);

praca_t = record
begin
  m_zadanie: zadanie_t;
  m_rezultat: rezultat_t;
  m_status: status_t;
  m_czekanie: condition;
end;

var
prace: array [1..N] of praca_t = { N times { .m_status = wolne } };
liczba_przetwarzanych_zadan: integer := 0;
klienci: condition;
pracownicy: condition;

procedure znajdz_miejsce(in status_t: p_status, out lokalizacja: 1..N, in ostatnio_uzywane: integer)
var i: integer;
begin
  for i:=ostatnio_uzywane+1 to N do
  begin
  	if (prace[i].m_status=p_status)
		lokalizacja := i;
		return;
  end;
  for i:=1 to ostatnio_uzywane do
  begin
  	if (prace[i].m_status=p_status)
		lokalizacja := i;
		return;
  end;
  lokalizacja := 0;
  return;
end;

export procedure zlecenie_przetwarzania(in p_zadanie: zadanie_t, out p_rezultat: rezultat_t)
var:
  lokalizacja: 1..N;
  praca_t: praca;
begin
  if (liczba_przetwarzanych_zadan=N) then
    wait(klienci);
  liczba_przetwarzanych_zadan++;
  
  znajdz_miejsce(wolne, lokalizacja, N);
  praca := prace[lokalizacja];
  praca.m_zadanie := p_zadanie;
  praca.m_status := oczekujace;
  signal(pracownicy);
  wait(praca.m_czekanie);
  p_rezultat := praca.m_rezultat;
  praca.m_status := wolne;

  liczba_przetwarzanych_zadan--;
  signal(klienci);
end;

export procedure pobieranie_zadania(out lokalizacja_rezultatu: 1..N, out p_zadanie: zadanie_t)
var
begin
  znajdz_miejsce(oczekujace, lokalizacja_rezultatu, lokalizacja_rezultatu);
  if (lokalizacja_rezultatu=0) then
  begin
    wait(pracownicy);
    znajdz_miejsce(oczekujace, lokalizacja_rezultatu, lokalizacja_rezultatu);
  end;
  praca := prace[lokalizacja_rezultatu];
  
  p_zadanie := praca.m_zadanie; 
  praca.m_status := przetwarzane;
end;

export procedure umieszczanie_rezultatu(in lokalizacja_rezultatu: 1..N, in p_rezultat: rezultat_t)
begin
  praca := prace[lokalizacja_rezultatu];
  praca.m_rezultat := p_rezultat;
  praca.m_status := gotowe;
  signal(praca.m_czekanie);
end;