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;
Synchronizacja grupowa
Wersja łatwiejsza
W pewnym systemie działa procesów i serwer. Procesy w pętli nieskończonej:
- załatwiają własne_sprawy,
- grupują się w zespoły po 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 procesów i serwer. Procesy w pętli nieskończonej:
- załatwiają własne_sprawy,
- grupują się w zespoły po 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.