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

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania

Zadanie 1

Treść

Stosując mechanizm komunikacji asynchronicznej omówiony na wykładzie rozwiąż problem wzajemnego wykluczania dla wielu procesów. Co zmieni się w rozwiązaniu, jeśli zezwolimy na pobyt w sekcji krytycznej jednocześnie K>0 procesom?

Rozwiązanie pierwsze

Przedstawione na wykładzie rozwiązanie działa dobrze także wtedy, gdy w systemie działa wiele procesów. Każdy z nich wykonuje kod:

process Pr (i: integer);
var
  k: Komunikat;
begin
  repeat
    własne_sprawy;
    GetMessage (b, k)
    sekja_krytyczna;
    SendMessage (b, k)
  until false
end;

Przed uruchomieniem procesów (powiedzmy, że jest ich P) musimy jeszcze zadbać o to, by w buforze b było K komunikatów:

const
  P = ...;
  K = ...;
type
  Komunikat = (Bilet); 
var i: integer;
begin
  for i := 1 to K do
    SendMessage (b, Bilet);
  cobegin 
    for i := 1 to P do Pr(i) 
  coend  
end

Rozwiązanie drugie. Serwer.

Częstym rozwiązaniem stosowanym w modelu rozproszonym jest wprowadzanie dodatkowych procesów, które nadzorują synchronizację pozostałych. Zastosujmy takie podejście do omawianego zadania. Wprowadźmy dodatkowy proces o nazwie Dozorca, który będzie nadzorował dostęp do sekcji krytycznej.

Ćwiczenie (ukrywajka)
O jakich zdarzeniach powinien informować dozorcę proces?
O czym powinien informować serwer?
Jakie bufory są potrzebne?

Schemat komunikacji

Każdy proces powinien wysyłać serwerowi informację o tym, że chce wejść do sekcji krytycznej. Serwer, po odebraniu takiego komunikatu, sprawdza, czy sekcja krytyczna jest wolna. Jeśli tak, to wysyła procesowi zgodę na wejście do niej. Proces powinien cierpliwie oczekiwać na zgodę serwera, po czym wejść do sekcji krytycznej dopiero po jej otrzymaniu. Następnie po zakończonym pobycie w sekcji musi poinformować serwer, że jest ona wolna.

Opisany schemat daje się zrealizować za pomocą dwóch buforów:

  • w pierwszym zam procesy umieszczają "zamówienia" na sekcję krytyczną
  • w drugim zezw serwer umieszcza zezwolenia na wejście do sekcji krytycznej
Rysunek przedstawiający ten schemat.

Treść procesu

Ćwiczenie (ukrywajka)
Napisz treść procesu

Przypuśćmy, że opisane powyżej komunikaty definiujemy za pomocą wartości typu wyliczeniowego:

type
  Komunikat = (Chcę, Możesz, Zwalniam);

i mamy bufory:

var
  zam, zezw: buffer;

Wtedy treść procesu wygląda tak:

process Pr (i: integer);
var
  k: Komunikaty;
begin
  repeat
    własne_sprawy;
    SendMessage (zam, Chcę);
    GetMessage (zezw, k);
    sekcja_krytyczna;
    SendMessage (zam, Zwalniam);
  until false
end