Rozwiązanie klasyczne

Rozwiązanie przedstawione poniżej przetwarza wiele żądań jednocześnie, i jednocześnie nie posiada mankamentu poprzedniego rozwiązania.

process Czytelnia
var:
  k: komunikat_typ;
  ilu_czytelnikow, ilu_czytelnikow_czyta: integer;
  ilu_pisarzy, ilu_pisarzy_pisze: integer;
  i: integer;
begin
  while (true) do
  begin
    k := GetMessage(operacje);
    case k of
      ChceCzytelnik:
        ilu_czytelnikow := ilu_czytelnikow + 1;
        if (ilu_pisarzy=0) then
          begin
            ilu_czytelnikow_czyta := ilu_czytelnikow_czyta + 1;
            SendMessage(moze_czytelnik, MozeCzytelnik);
          end;
      ChcePisarz:
        ilu_pisarzy := ilu_pisarzy + 1;
        if (ilu_czytelnikow=0 and ilu_pisarzy_pisze=0) then
          begin
            ilu_pisarzy_pisze := ilu_pisarzy_pisze + 1;
            SendMessage(moze_pisarz, MozePisarz);
          end;
      ZwalniaCzytelnik:
        ilu_czytelnikow_czyta := ilu_czytelnikow_czyta - 1;
        ilu_czytelnikow := ilu_czytelnikow - 1;
        if (ilu_czytelnikow_czyta=0) then
          begin
            if (ilu_pisarzy>0) then
              begin
                ilu_pisarzy_pisze++;
                SendMessage(moze_pisarz, MozePisarz);
              end;
          end;
      ZwalniaPisarz:
          ilu_pisarzy_pisze := ilu_pisarzy_pisze - 1;
          ilu_pisarzy := ilu_pisarzy - 1;
          if (ilu_czytelnikow>0) then
            begin
              for i:=1 to ilu_czytelnikow do
              begin
                ilu_czytelnikow_czyta := ilu_czytelnikow_czyta + 1;
                SendMessage(moze_czytelnik, MozeCzytelnik);
              end;
            end;
          else if (ilu_pisarzy>0) then
            begin
              ilu_pisarzy_pisze := ilu_pisarzy_pisze + 1;
              SendMessage(moze_pisarz, MozePisarz);
            end;
    end; {case}
  end; 
end;