Table of Contents
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;