Łącze internetowe jest dzielone między wielu użytkowników. Szerokość pasma wynosi N. Użytkownik chcąc korzystać z łącza, rezerwuje potrzebną szerokość (potrzebna_szerokosc>0 i potrzebna_szerokosc<=N) pasma. Użytkonik zwalnia zarezerwowaną szerokość pasma, gdy skończy z niego korzystać. Zsynchronizuj użytkowników, aby mogli korzystać z połączenia zgodnie ze swoimi potrzebami.
const N = ...; LICZBA_UZYTKOWNIKOW = ...; procedure rezerwacja_pasma(szerokosc_dla_uzytkownika: integer) begin ... end; procedure zwalnianie_pasma(szerokosc_dla_uzytkownika: integer) begin ... end; process Uzytkownik(i: integer) var szerokosc_dla_uzytkownika: integer; begin while (true) do begin wlasne_sprawy(); szerokosc_dla_uzytkownika := losuj(1, N); rezerwacja_pasma(szerokosc_dla_uzytkownika); korzystanie_z_lacza(); zwalnianie_pasma(szerokosc_dla_uzytkownika); end; end; var i: integer; begin cobegin for i:=1 to LICZBA_UZYTKOWNIKOW do begin Uzytkownik(i); end; coend; end;
Do rozwiązania tego problemy można wykorzystać metodę Pojedynczego Przetwarzania Żądań. Przetwarzanie żadania rezerwacji opakowujemy semaforem binarnym, w ten sposób przetwarzamy pojedynczo żądania.
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); 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 szerokosc_potrzebna:=-1; V(czekajacy_uzytkownik); end; V(ochrona); end;