Programowanie współbieżne i rozproszone/PWR Ćwiczenia Ada
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;