Programowanie współbieżne i rozproszone/PWR Ćwiczenia Ada

From Studia Informatyczne

Spis treści

Czytelnicy i pisarze

Rozwiąż problem czytelników i pisarzy w Adzie.

Rozwiązanie

Wersja standardowa

task Serwer is 
  entry ChceCzytać;
  entry ChcePisać (nr: in Integer);
  entry Koniec;
end Serwer;
task body Serwer is 
var
  iluczyta: Integer := 0;
  numer: Integer;
loop
  select
    accept Koniec;
    iluczyta := iluczyta - 1;
  or
    accept ChceCzytać;
    iluczyta := iluczyta + 1;
  or 
    accept ChcePisać (nr: in Integer) do 
      numer := nr;
    end ChcePisać;
    while iluczyta > 0 loop 
      accept Koniec;
      iluczyta := iluczyta - 1;
    end loop
    Pisarz(numer).Możesz;
    accept Koniec; 
  end select;
end loop;
end Serwer;        
       

Wersja bez wejść w procesach

task Serwer is 
  entry ChceCzytać;
  entry ChcePisać;
  entry Koniec;
end Serwer;
task body Serwer is 
var
  iluczyta: Integer := 0;
loop
  select
    accept Koniec;
    iluczyta := iluczyta - 1;
  or
    accept ChceCzytać;
    iluczyta := iluczyta + 1;
  or 
    accept ChcePisać  do
      while iluczyta > 0 loop 
        accept Koniec;
        iluczyta := iluczyta - 1;
      end loop;
    end ChcePisać; 
    accept Koniec; 
  end select;
end loop;
end Serwer;        
       

Wersja z możliwością zmiany roli

W pewnym systemie działają procesy, z których każdy cyklicznie załatwia własne_sprawy, po czym wchodzi do sekcji_krytycznej. Dostęp do sekcji krytycznej może być wyłączny albo dzielony. Proces żądający wyłącznego dostępu do sekcji krytycznej przebywa w niej jako jedyny. Proces żądający dostępu dzielonego może korzystać z sekcji krytycznej w tym samym czasie, co inne procesy żądające dostępu dzielonego. Wiadomo ponadto, że każdy proces przebywający w sekcji krytycznej co najwyżej raz zażąda zmiany sposobu korzystania z sekcji. Procesy żądające zmiany sposobu dostępu z dzielonego na wyłączny zostają wstrzymane do momentu, w którym będą mogły korzystać z sekcji na zasadzie wyłączności. Mają one przy tym pierwszeństwo przed nowymi procesami. Zapisz w Adzie proces Serwer synchronizujący dostęp do sekcji krytycznej zgodnie z powyższym opisem. Jedyne wejścia znajdują się w Serwerze i są to:

  • wyłączny,
  • dzielony,
  • zmiana i
  • koniec.
task Serwer is 
  entry Dzielony;
  entry Wyłączny;
  entry Koniec;
  entry Zmiana;
end Serwer;
task body Serwer is 
var
  iluczyta: Integer := 0;
procedure Czekaj is
  while iluczyta > 0 loop 
    select 
      accept Koniec;
      iluczyta := iluczyta - 1;
    or
      accept Zmiana do
        Czekaj;
      end Zmiana;
      accept Koniec;
    end select;
  end loop;
   
loop
  select
    accept Koniec;
    iluczyta := iluczyta - 1;
  or
    accept Dzielony;
    iluczyta := iluczyta + 1;
  or
    accept Zamiana do;  
  or
    accept Wyłączny  do
      Czekaj;       
    end Wyłączny; 
    select
      accept Koniec; 
    or
      accept Zmiana;
      iluczyta := 1;
    end select;
  end select;
end loop;
end Serwer;        

Synchronizacja grupowa

Wersja łatwiejsza

W pewnym systemie działa N > 0 procesów i serwer. Procesy w pętli nieskończonej:

  • załatwiają własne_sprawy,
  • grupują się w zespoły po 0<K<N procesów,
  • synchronizuj± się w obrębie zespołu.

Każdy proces, który zakończył własne sprawy wywołuje wejście serwera Zespół (nr: in 1..N. Następnie czeka na swoim wejściu Komplet (i: in 1..K; numery: in array[1..K] of 1..N) aż skompletuje się zespół. Parametr nr jest numerem wywołującego procesu, tablica numery zawiera numery wszystkich członków zespołu oraz pozycję i, pod którą dany proces znajduje się w tej tablicy. Następnie każdy członek zespołu synchronizuje się ze wszystkimi pozostałymi członkami zespołu bezpośrednio wywołując ich wejścia Synchro (tzn. każdy proces wywołuje wejście Synchro każdego innego procesu z tego zespołu), po czym znów zajmuje się własnymi sprawy. Napisz w Adzie treść procesów Proces (1..N) oraz Serwer. Jedynym wejściem w serwerze jest Zespół, a jedynymi wejściami w procesie są Synchro oraz Komplet.

Wersja bez wejść w procesach

W pewnym systemie działa N > 0 procesów i serwer. Procesy w pętli nieskończonej:

  • załatwiają własne_sprawy,
  • grupują się w zespoły po 0<K<N procesów,
  • synchronizuj± się w obrębie zespołu.

Każdy proces, który zakończył własne sprawy wywołuje wejście serwera Komplet (nr: in 1..N; i: out 1..K; numery: out array[1..K] of 1..N), na którym czeka aż skompletuje się zespół. Parametr nr jest numerem wywołującego procesu, tablica numery zawiera numery wszystkich członków zespołu oraz pozycję i, pod którą dany proces znajduje się w tej tablicy. Następnie każdy członek zespołu synchronizuje się ze wszystkimi pozostałymi członkami zespołu bezpośrednio wywołując ich wejścia Synchro (tzn. każdy proces wywołuje wejście Synchro każdego innego procesu z tego zespołu), po czym znów zajmuje się własnymi sprawy. Napisz w Adzie treść procesów Proces (1..N) oraz Serwer. Jedynym wejściem w serwerze jest Komplet, a jedynym wejściem w procesie jest Synchro.