2021-04-11
Zaimplementować program współbieżny symulujący system, w którym nadawca wysyła do odbiorcy autonomiczne pakiety podróżujące po acyklicznym grafie skierowanym z jednym źródłem i z jednym ujściem.
Wierzchołki grafu G są indeksowane liczbami naturalnymi od do . Wierzchołek jest źródłem, a wierzchołek jest ujściem.
Dla każdego , istnieje w grafie krawędź skierowana , co zapewnia, że z każdego wierzchołka jest jakaś ścieżka skierowana do ujścia.
Ponadto w grafie istnieje pewna liczba dodatkowych krawędzi postaci , gdzie (tzw. skrótów).
Dla wierzchołka , zbiorem następników , , nazywamy zbiór takich , że istnieje krawędź .
Program ma działać następująco:
- Generowany jest graf dla podanych parametrów i , gdzie skrótów generowane jest w sposób losowy.
- Graf drukowany jest na terminalu tak, aby przedstawić istniejące połączenia. (Zastanowić się nad tym, jaki sposób prezentacji będzie najbardziej czytelny.)
- Uruchamiana jest symulacja systemu przesyłania pakietów po grafie .
System przesyłania pakietów działa według następujących zasad:
- W jednym wierzchołku może przebywać tylko jeden pakiet.
- Co pewien losowy czas nadawca umieszcza w źródle (o ile jest ono puste) nowy pakiet indeksowany kolejną liczbą naturalną.
- Co pewien losowy czas odbiorca odbiera z ujścia pakiet (o ile jest co odebrać).
- Pakiet w wierzchołku , po odczekaniu losowego czasu, wybiera losowo jeden wierzchołek ze zbioru i czeka, aż będzie mógł się do niego przemieścić.
- Gdy pakiet dotrze do wierzchołka i drukowany jest komunikat: „pakiet jest w wierzchołku ”
- i jednocześnie dodaje do swojej listy odwiedzonych wierzchołków oraz dodaje do swojej listy obsłużonych pakietów.
- Gdy odbiorca odbierze pakiet , drukuje komunikat: „pakiet został odebrany”.
- Po nadaniu pakietów nadawca kończy nadawanie.
Gdy odbiorca odbierze ostatni (tj. -ty) pakiet, system kończy działanie i rozpoczyna się drukowanie raportów końcowych.
W raportach końcowych pojawią się dwa wykazy:
- dla każdego wierzchołka, lista kolejno obsłużonych przez niego pakietów,
- dla każdego pakietu, lista odwiedzonych przez niego wierzchołków (ścieżka od źródła do ujścia).
Zaimplementuj system tak, aby nadawca, odbiorca oraz każdy wierzchołek grafu były osobnymi wątkami współbieżnymi, które przekazują sobie pakiety przez narzędzia komunikacji między wątkami.
Zwróć uwagę, że komunikaty drukowane przez współbieżne wątki na terminalu mogą się przeplatać. Dlatego dodaj nowy wątek (serwer drukowania), który przyjmuje zlecenia drukowania komunikatów od wątków i niezwłocznie, ale sekwencyjnie, drukuje je na ekranie w osobnych liniach.
Przetestuj działanie swojego programu przy różnych wartościach parametrów i różnych ograniczeniach na losowe opóźnienia w działaniach wątków. Do prezentacji w
asciinema
wybierz takie parametry, aby jak najlepiej to wyglądało.Wskazówki:
- Każdy koniec kanału w Go może być używany przez różne współbieżne wątki.
- Obejrzyj podgląd pliku common_channel.go (w tym samym katalogu Dysku Google) zawierający przykład wspólnego używania kanału przez różne wątki oraz wykorzystania generatora liczb losowych.
Pliki Źródłowe znajdują się w katalogu go
.
Żeby uruchomić program, należy wykonać polecenie
go run . ‹n› ‹d› ‹k› ‹maxSleep›
z uzupełnionymi parametrami.
Parametr maxSleep
określa liczbę, przez jaką należy podzielić domyślny czas oczekiwania wątków (jedna sekunda). Przykładowo, jeśli maxSleep = 100
oznacza to, że maksymalny czas oczekiwania wynosi 1/100
sekundy, czyli 10
milisekund.
Nagranie asciinema
znajduje się w pliku go.cast
.
Pliki źródłowe znajdują się w katalogu ada
.
Przed uruchomieniem programu należy go skompilować poleceniem
make
Teraz można uruchomić program poleceniem
./main.bin ‹n› ‹d› ‹k› ‹maxSleep›
z uzupełnionymi parametrami.
Parametr maxSleep
określa liczbę, przez jaką należy podzielić domyślny czas oczekiwania wątków (jedna sekunda). Przykładowo, jeśli maxSleep = 100
oznacza to, że maksymalny czas oczekiwania wynosi 1/100
sekundy, czyli 10
milisekund.
Nagranie asciinema
znajduje się w pliku ada.cast
.