Chapter 5. Zadania z kolokwiów

Table of Contents

Wycieczki
Dyskoteka
Gracze
Grupy Procesów
Zasoby

Wycieczki

Górski punkt wycieczkowy organizuje wycieczki w góry o T>=1 stopniach trudności. Wycieczki prowadzą przewodnicy. Każdy przewodnik ma uprawnienia wyrażone liczbą od 1 do T, przy czym przewodnik o uprawnieniach t może kierować wycieczką o trudności nie większej niż t. Dla każdego 1<=t<=T jest co najmniej jeden przewodnik o uprawnieniach t.

Liczność grupy zależy od stopnia trudności wycieczki: na wycieczkę o trudności t może wyjść grupa od GMIN(t) do GMAX(t) (włącznie) uczestników i dokładnie jeden przewodnik. Wiadomo przy tym, że dla każdego t GMIN(t)<=t<=GMAX(t).

Uczestnik cyklicznie wykonuje WŁASNE SPRAWY, losuje poziom trudności kolejnej wycieczki (funkcja LOSUJ(T)) i, być może po oczekiwaniu na grupę i/lub przewodnika, wraz z grupą i przewodnikiem wybiera się na wycieczkę (procedura WYCIECZKA(nr_przewodnika :integer)).

Przewodnik cyklicznie wykonuje WŁASNE_SPRAWY, zgłasza się do pracy, zabiera na wycieczkę pewną skompletowaną (o liczności>=GMIN(t)) grupę, wybierając przy tym wycieczkę o największej trudności, spośród tych, które jest w stanie poprowadzić. Jeśli żadna grupa nie jest gotowa lub przewodnik nie ma wystarczających uprawnień, to przewodnik musi poczekać.

Gdy zbierająca się grupa osiągnie liczność GMIN(t) i czeka pewien przewodnik o uprawnieniach>=t, to jest budzony przewodnik o najniższych dostatecznych uprawnieniach spośród oczekujących przewodników. Zabiera on grupę na wycieczkę (procedura WYCIECZKA).

Po zakończeniu wycieczki każdy przewodnik i uczestnik (bez synchronizacji z innymi) rozpoczyna ponownie wykonanie WŁASNYCH_SPRAW. Zapisz treść procesów Przewodnik(nr: integer; upr: 1..T) i Uczestnik, używając do synchronizacji semaforów ogólnych i/lub binarnych. Parameter nr jest unikatowym numerem przewodnika, a upr określa jego uprawnienia. Pamiętaj o zainicjowaniu wszystkich zmiennych.

Rozwiązanie:

var
 przewodnik: array[1..T] of binary semaphore := {T times 0};
 l_cz_przewodnikow: array[1..T] of integer := {T times 0};
 uczestnik: array[1..T] of binary semaphore := {T times 0};
 l_cz_uczestnikow: array[1..T] of integer := {T times 0};
 gotowa_grupa: integer;
 przewodnik_id: integer;
 liczba_do_wpuszczenia: integer;

process wycieczka_przewodnik(id: integer, stopien: integer)
 var i;
begin
 P(ochrona);
 for i=stopien downto 1 do
 begin
  if (l_cz_uczestnikow>=GMIN(i)) then
  begin gotowa_grupa:=i; break end;
 end;
 if (gotowa_grupa=0) then
 begin
  l_cz_przewodnikow[stopien]++;
  V(ochrona);
  P(przewodnik[stopien]);
  l_cz_przewodnikow[stopien]--;
 end;
 przewodnik_id := id;
 liczba_do_wpuszczenia := MIN(l_cz_uczestnikow[gotowa_grupa], GMAX(gotowa_grupa));
 if (liczba_do_wpuszczenia>0)
 	V(uczestnik[gotowa_grupa]);
 else
	V(ochrona);
end;

process wycieczka_uczestnik(var id: integer, stopien: integer)
var
 i: integer;
 st_przewodnik: integer := 0;
begin
 P(ochrona);
 l_cz_uczestnikow[stopien]++;
 if (l_cz_uczestnikow[stopien]>=GMIN(stopien)) then
 begin
  for i:=stopien to T do
  begin
   if (l_cz_przewodnikow[i]>0) then
   begin
    st_przewodnik:=i;
    break;
   end;
  end;
 end;
 if (st_przewodnik!=0) then
 begin
  gotowa_grupa := stopien;
  V(przewodnik[st_przewodnik]);
 end;
 else
  V(ochrona);
 P(uczestnik[stopien]);
 id := przewodnik_id;
 l_cz_uczestnikow[stopien]--; 
 liczba_do_wpuszczenia--;
 if (liczba_do_wpuszczenia>0)
  V(uczestnik[stopien]);
 else
  V(ochrona);
end;