Programowanie współbieżne i rozproszone/PWR Ćwiczenia 10: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Mengel (dyskusja | edycje)
Nie podano opisu zmian
 
Mengel (dyskusja | edycje)
Nie podano opisu zmian
Linia 6: Linia 6:
stolik tylko wtedy, gdy obydwa są gotowe do spotkania, ale odchodzą od niego
stolik tylko wtedy, gdy obydwa są gotowe do spotkania, ale odchodzą od niego
pojedyńczo (w różnym czasie kończą wykonywanie procedury randka)
pojedyńczo (w różnym czasie kończą wykonywanie procedury randka)
Zapisz treć procesu {\tt P(j: 1..N)} i monitor {\tt KAWIARNIA}
Zapisz treść procesu P(j: 1..N) i monitor KELNER
synchronizuj±cy ich działanie. \\
synchronizujący ich działanie.


\noindent {\bf Rozwi±zanie a}
monitor KELNER
%%--------------------------------------------------------------------------
var
\begin{verbatim}
  NA_PARĘ : array [1..N] of condition;
var
  NA_STÓŁ : condition;
  NA_PARĘ : array [1..N] of binary semaphore := (0,...,0);
  przy_stole : integer;
  para : array [1..N] of boolean := (False, ...,False);
export procedure CHCĘ_STOLIK(j:integer)
  NA_STÓŁ : binary semaphore := 1;
begin
  przy_stole : integer := 0;
  if empty(NA_PARĘ[j]) then wait(NA_PARĘ[j])
  OCHRONA : binary semphore := 1;
  else begin
 
          if przy_stole > 0 then wait(NA_STÓŁ);
process P(j:1..N)
          przy_stole := 2;
begin
          signal(NA_PARĘ[j])
  repeat
        end
    własne_sprawy;
end;
    P(OCHRONA);
export procedure ZWALNIAM
    if not para[j] then begin
begin
                          para[j] := True;
  przy_stole := przy_stole - 1;
                          V(OCHRONA);
  if przy_stole = 0 then signal(NA_STÓŁ);
                          P(NA_PARĘ[j]);
end;
                        end
begin
    else begin
  przy_stole := 0;
          para[j] := False;
end.
          V(OCHRONA);
          P(NA_STÓŁ);
          przy_stole := 2;
          V(NA_PARĘ[j]);
    end;
    randka;
    P(OCHRONA);
    dec(przy_stole);
    if przy_stole = 0 then begin
                            V(OCHRONA);
                            V(NA_STÓŁ);
                      end
    else V(OCHRONA);
  until false;
end;
 
\end{verbatim}
 
\noindent {\bf Rozwi±zanie b}
 
\begin{verbatim}
monitor KELNER
var
  NA_PARĘ : array [1..N] of condition;
  NA_STÓŁ : condition;
  przy_stole : integer;
 
export procedure CHCĘ_STOLIK(j:integer)
begin
  if empty(NA_PARĘ[j]) then wait(NA_PARĘ[j])
  else begin
        if przy_stole > 0 then wait(NA_STÓŁ);
        przy_stole := 2;
        signal(NA_PARĘ[j]);
      end;
end;
 
export procedure ZWALNIAM
begin
  dec(przy_stole);
  if przy_stole = 0 then signal(NA_STÓŁ);
end;
 
begin
  przy_stole := 0;
end.


process P(j:1..N)
process P(j:1..N)
Linia 89: Linia 43:


== Bar piwny ==
== Bar piwny ==
Napisz monitor BAR synchronizujący pracę barmana obsługującego klientów przy kolistym barze z $N$ stołkami. Każdy klient realizuje następujący algorytm:
Napisz monitor BAR synchronizujący pracę barmana obsługującego klientów przy kolistym barze z N stołkami. Każdy klient realizuje następujący algorytm:
  var
  var
   i : integer;
   i : integer;
Linia 116: Linia 70:
  var  
  var  
   ilu_w: integer;      { ilu klientów jest w barze }
   ilu_w: integer;      { ilu klientów jest w barze }
   WEJSCIE: condition;  { tu klienci czekaj± na wej¶cie do baru }
   WEJSCIE: condition;  { tu klienci czekają na wejście do baru }


   stołek: array [0..N-1] of (wolny, nieobsłużony, obsłużony);  
   stołek: array [0..N-1] of (wolny, nieobsłużony, obsłużony);  

Wersja z 13:27, 3 paź 2006

Stolik dwuosobowy

W systemie działa N par procesów. Procesy z pary są nierozróżnialne. Każdy proces cyklicznie wykonuje własne_sprawy, a potem spotyka się z drugim procesem z pary (procedura randka) w kawiarni przy stoliku dwuosobowym. W kawiarni jest tylko jeden stolik. Procesy mogą zająć stolik tylko wtedy, gdy obydwa są gotowe do spotkania, ale odchodzą od niego pojedyńczo (w różnym czasie kończą wykonywanie procedury randka) Zapisz treść procesu P(j: 1..N) i monitor KELNER synchronizujący ich działanie.

monitor KELNER
var
  NA_PARĘ : array [1..N] of condition;
  NA_STÓŁ : condition;
  przy_stole : integer;
export procedure CHCĘ_STOLIK(j:integer)
begin
  if empty(NA_PARĘ[j]) then wait(NA_PARĘ[j])
  else begin
         if przy_stole > 0 then wait(NA_STÓŁ);
         przy_stole := 2;
         signal(NA_PARĘ[j])
       end
end;
export procedure ZWALNIAM
begin
  przy_stole := przy_stole - 1;
  if przy_stole = 0 then signal(NA_STÓŁ);
end;
begin
  przy_stole := 0;
end.

process P(j:1..N) begin

 repeat
   własne_sprawy;
   KELNER.CHCĘ_STOLIK(j);
   randka;
   KELNER.ZWALNIAM;
 until false;

end

Bar piwny

Napisz monitor BAR synchronizujący pracę barmana obsługującego klientów przy kolistym barze z N stołkami. Każdy klient realizuje następujący algorytm:

var
  i : integer;
begin
  repeat   
    BAR.CZEKAJ_NA_STOŁEK_I_PIWO(i);
    <pije piwo na stołku i-tym>
    BAR.ZWALNIAM(i);
  until false;
end;

Barman nalewa piwo nowo przybyłym klientom w kolejności wyznaczonej przez stołki przez nich zajmowane (chodzi "w kółko"):

var
  i : integer;
begin
  repeat   
    BAR.KTO_NASTĘPNY(i);
    <podejście do stołka i-tego i nalanie piwa>
    BAR.ZACZNIJ_PIĆ(i);
  until false;
end;
monitor BAR;
var 
 ilu_w: integer;       { ilu klientów jest w barze }
 WEJSCIE: condition;   { tu klienci czekają na wejście do baru }
 stołek: array [0..N-1] of (wolny, nieobsłużony, obsłużony); 
 czeka: array [0..N-1] of condition;  { tu klient czeka na nalanie piwa }
 ilu_czeka: integer;    { ilu klientów czeka na nalanie piwa }
 BARMAN: condition;    
export procedure CZEKAJ_NA_STOŁEK_I_PIWO(var i: integer);
begin
  if ilu_w = N then wait(WEJSCIE); 
  inc(ilu_w);
  inc(ilu_czeka);
  i := 0;
  while stołek[i] <> wolny do    
    i := (i + 1) mod N; 
  stołek[i] := nieobsłużony;     
  signal(BARMAN); 
  wait(czeka[i]);                
end;
export procedure ZWALNIAM(i: integer);
begin
  dec(ilu_w);
  stołek[i] := wolny;
  signal(WEJSCIE);
end;
export procedure KTO_NASTĘPNY(var i:integer);
begin
  if ilu_czeka = 0 then wait(BARMAN); 
  i := (i + 1) mod N; 
  while stołek[i] <> nieobsłużony do
    i := (i + 1) mod N;
end;
export procedure ZACZNIJ_PIĆ(i: integer);
begin
  stołek[i] := obsłużony; 
  dec(ilu_czeka);
  signal(czeka[i]);
end;
begin
for i:=0 to N do 
  stołek[i] := wolny;
end.