Klub grających w Grę liczy N>4 członków i ma salę z S>1 czteroosobowymi stolikami do gry. Partia Gry jest rozgrywana między dwoma parami graczy. Podczas spotkań klubowych 1<2P<N najsilniejszych graczy gra wyłącznie ze swoimi stałymi parnerami, pozostali dobierają się w pary dynamicznie. Stałe pary mają ustalone unikatowe identyfikatory (od 1 do P), pozostali mają identyfikator 0.
Gracz przychodzący na spotkanie klubowe, jeśli ma stałego partnera czeka na niego. Gracz bez stałego partnera tworzy parę z innym pojawiającym się graczem bez stałego partnera.
Aby możliwe było rozpoczęcie rozgrywki muszą być dwie pary graczy i wolny stolik. Rozegranie partii polega na wykonaniu przez każdego z graczy procedury rozgrywam_Grę. Po jej zakończeniu gracze odchodzą od stolika pojedynczo. Stolik staje się wolny, gdy odejdzie od niego ostani gracz.
Korzystając z semaforów binarnych i/lib ogólnych zapisz treść procesu Gracz(id_pary: 0..P).
Rozwiązanie:
type stolik_stan = {wolny, zajety}; var ochrona: binary semaphore := 1; czeka_para: array [1..P] of binary semaphore := P TIMES 0; liczba_czeka_para: array [1..P] of integer := P TIMES 0; liczba_par_gotowych: integer := 0; czeka_dynamiczny: binary semaphore := 0; liczba_czeka_dynamiczny: integer := 0; stolik : semaphore := S stolik_stan: array [1..S] of stolik_stan := S times wolny; liczba_przy_stoliku: array [1..S] of integer := S times 0; aktualny_stolik_id: integer; plan_budzenia: array [1..4] of (reference to) binary semaphore; ochrona_stolikow: binary semaphore := 1; process Gracz(id_para: 0..N) var stolik_id: integer; begin if (id_para=0) GraczDynamicznyStart(); else GraczParaStart(id_para); rozgrywam_Gre(); GraczKoniec(); end; procedure GraczDynamicznyStart(var stolik_id: integer) begin P(ochrona); if (liczba_par_gotowych>0) and (liczba_czeka_dynamiczny>0) then begin P(stolik); aktualny_stolik_id := rezerwuj_stolik(); para := znajdz_gotowa_pare(); plan_budzenia := { 1 -> czeka_dynamiczny; 2 -> czeka_para[para]; 3 -> czeka_para[para]; 4 -> ochrona; } P(ochrona_stolikow); end; else if (liczba_czeka_dynamiczny>2) then begin P(stolik); aktualny_stolik_id := rezerwuj_stolik(); plan_budzenia := { 1 -> czeka_dynamiczny; 2 -> czeka_dynamiczny; 3 -> czeka_dynamiczny; 4 -> ochrona; } P(ochrona_stolikow); end; else begin liczba_czeka_dynamiczny++; V(ochrona); P(czeka_dynamiczny); liczba_czeka_dynamiczny--; end; stolik_id := aktualny_stolik_id; liczba_przy_stoliku[stolik_id]++; V(plan_budzenia[liczba_przy_stoliku[stolik_id]]); end; procedure GraczParaStart(id: 1..N, var stolik_id: integer) var para: integer; begin P(ochrona); if (liczba_czeka_para[id]=1 and liczba_czeka_dynamiczny>1) then begin P(stolik); aktualny_stolik_id := rezerwuj_stolik(); para := znajdz_gotowa_pare(); plan_budzenia := { 1 -> czeka_para[id]; 2 -> czeka_para[para]; 3 -> czeka_para[para]; 4 -> ochrona; } P(ochrona_stolikow); end; else if (liczba_czeka_para[id]=1 and liczba_par_gotowych>0) begin P(stolik); aktualny_stolik_id := rezerwuj_stolik(); plan_budzenia := { 1 -> czeka_para[id]; 2 -> czeka_dynamiczny; 3 -> czeka_dynamiczny; 4 -> ochrona; } P(ochrona_stolikow); end; else begin liczba_czeka_para[id]++; if (liczba_czeka_para[id]==2) then liczba_par_gotowych++; V(ochrona); P(czeka_para[id]); if (liczba_czeka_para[id]==2) then liczba_par_gotowych--; liczba_czeka_para[id]--; end; stolik_id := aktualny_stolik_id; liczba_przy_stoliku[stolik_id]++; if (liczba_przy_stoliku[stolik_id]==4) then V(ochrona_stolikow); V(plan_budzenia[liczba_przy_stoliku[stolik_id]]); end; procedure GraczKoniec(stolik_id: integer) begin P(ochrona_stolikow); liczba_przy_stoliku[stolik_id]--; if (liczba_przy_stoliku[stolik_id]=0) then begin stan_stolika[stolik_id] := wolny; V(stolik); end; V(ochrona_stolikow); end;