Rozwiązanie niepoprawne

Warto zwrócić także uwagę na błędną implementację, w której błąd jest bardzo subtelny.

var
  szerokosc_niezarezerwowana: integer := N;
  szerokosc_potrzebna: integer := -1;
  rozpatrywanie_rezerwacji_pojedynczo: binary semaphore := 1;
  czekajacy_uzytkownik: binary semaphore := 0;
  ochrona: binary semaphore := 1;

procedure rezerwacja_pasma(szerokosc_dla_uzytkownika: integer)
begin
  P(rozpatrywanie_rezerwacji_pojedynczo);
  P(ochrona);
  if (szerokosc_dla_uzytkownika<szerokosc_niezarezerwowana) then
    begin
      szerokosc_potrzebna := szerokosc_dla_uzytkownika;
      V(ochrona);
      P(czekajacy_uzytkownik);
      P(ochrona);
      szerokosc_potrzebna:=-1;{dodana instrukcja}
    end;
  szerokosc_niezarezerwowana := szerokosc_niezarezerwowana - szerokosc_dla_uzytkownika;
  V(ochrona);
  V(rozpatrywanie_rezerwacji_pojedynczo); 
end;

procedure zwalnianie_pasma(szerokosc_dla_uzytkownika: integer)
begin
  P(ochrona);
  szerokosc_niezarezerwowana := szerokosc_niezarezerwowana + szerokosc_dla_uzytkownika;
  if (szerokosc_potrzebna<>-1 and szerokosc_niezarezerwowana>=szerokosc_potrzebna) then
  begin
    {usunieta instrukcja szerokosc_potrzebna:=-1}
    V(czekajacy_uzytkownik); 
  end;
  V(ochrona);
end;

W tej implementacji semafor czekajacy_uzytkownik może zostać podniesiony dwa (a nawet więcej) razy. Dzieje się tak dlatego, że proces, który budzi proces czekający na semaforze czekajacy_uzytkownik powinien zapewnić, że inny proces zwracający pasmo nie będzie już drugi raz podnosił semafora czekajacy_uzytkownik, a tego nie robi. W rozwiązaniu poprawnym jest to zapewnione gdyż proces, który jako pierwszy budzi proces czekający na semaforze czekajacy_uzytkownik ustawia szerokosc_potrzebna na -1 i tym samym powoduje, że nikt inny nie będzie budził czekającego na semaforze czekajacy_uzytkownik procesu.