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;