Zapoznaj się z
- Tworzeniem procesów.
- Rejestracja procesów.
- Komunikacja między procesami.
W Eshellu
%%Tworzenie procesów.
>
> spawn(fun() -> io:format("To jest tekst~n") end).
>
> F = ... %definicja Twojego funa!
> spawn(F).
%% Przesyłanie wiadomości
> Proces1 = spawn(fun() ->
> receive
> _ -> io:format("Otrzymalem wiadomosc!~n")
> end
> end).
> Proces1 ! ... % wyślij jakąś wiadomość
> Proces1 ! ... % jeszcze raz
% Co się stało ? I dlaczego ?
...
%% Teraz stworzymy proces który przetrzymuje jakiś stan.
%% By to zrobić, wpierw musimy zdefinować funkcjonalność procesu.
% Funkcjonalność procesu
> IncLoop = fun Loop(N) ->
> receive
> inc -> Loop(N+1);
> print -> io:format("~B~n",[N]), Loop(N);
> stop -> ok
> end
> end.
>
%% Tworzenie procesu
%% Zwróć uwagę na funa...
> Proces2 = spawn(fun() -> IncLoop(0) end).
%% Czy poniższa linijka zadziała ?
> Proces3 = spawn(IncLoop).
% Dlaczego ?
...
%% Co robi ta linijka ?
> register(proces_stanu, Proces2).
%% Teraz mamy bardziej skomplikowany proces, który zarządza jakimś stanem
%% Co jest tym stanem ?
...
%% Co możemy robić z tym stanem ?
...
%% Komunikacja z procesem stanu.
> Proces2 ! inc.
> proces_stanu ! print.
> proces_stanu ! inc.
> Proces2 ! print.
- Poszerzenie wiedzy dotyczącej Erlangowych procesów.
- Poznanie sposobów łączenia węzłów zdalnych
Celem zajęć jest zapoznanie się z procesami w Erlangu, poznanie mechanizmów ich tworzenia, rejestracji, i komunikacji.
- Pobierz plik z testami modułu pollution
- wypakuj w miejsce, w którym znajduje się Twoja implementacja modułu pollution
- oba modułu skompiluj używając:
c(pollution).
,c(pollution_test).
- uruchom
eunit:test([pollution_test]).
- Napisz moduł pingpong, który będzie eksportował funkcje:
start/0
, która utworzy 2 procesy i zarejestruje je pod nazwamiping
ipong
,stop/0
, która zakończy oba procesy,play/1
, która wyśle wiadomość z liczbą całkowitą N do procesuping
.
- Po otrzymaniu wiadomości, proces
ping
ma rozpocząć wymianę N wiadomości z procesempong
. Przy odebraniu każdej wiadomości procesy mają wypisać na standardowe wyjście informację o przebiegu odbijania. - Dla zwiększenia czytelności działania warto użyć funkcji
timer:sleep(Milisec)
. - Procesy
ping
ipong
powinny samoczynnie kończyć działanie po 20 sekundach bezczynności. - Zmodyfikuj proces
ping
by przechowywał stan - sumę wszystkich liczb z komunikatów, które otrzymał. Dodaj tę sumę do informacji wypisywanej po odebraniu komunikatu.
Dane są 2 listy punktów na płaszczyźnie 2D:
- lista lokalizacji paczkomatów, których jest np.
1000
- lista rozmieszczenia osób, które chcą odwiedzić paczkomat - jest ich np.
20000
Szukamy osoby, która jest najbliżej dowolnego paczkomatu.
- Przygotuj dane - 2 listy par liczb całkowitych z zakresu
0
-10000
, wygenerowane losowo. Użyj list comprehensions. - Napisz pomocniczą funkcję
dist({X1, Y1}, {X2, Y2})
, która zwróci dystans między punktami.
Wersja sekwencyjna:
- Napisz funkcję
findMinDistance(PeopleLocations, LockerLocations)
, która wyszuka osobę i zwróci{dystans, {pozycjaOsoby, pozycjaPaczkomatu}}
. Do wyznaczenie wszystkich dystansów można użyć list comprehension. Wyszukanie najbliższej może zrealizować funkcjalists:min
. - Zmierz czas wykonania funkcji
Wersja bardzo równoległa:
- Napisz wersję funkcji
findMinDistance(PeopleLocations, LockerLocations, ParentPID)
, która po obliczeniu wyniku odsyła go do podajego Pid. - Napisz funkcję, która uruchomi wyszukiwanie w osobnym procesie dla każdej osoby oddzielnie.
- Odbierz komunikaty, zbierz wszystkie wyniki od procesów w liście.
- Zarówno tworzenie procesów jak i odbieranie wyników można zrealizować używając list comprehension.
- Wyszukanie wyniku może zrealizować funkcja
lists:min
. - Porównaj czas obliczeń.
Wersja mniej równoległa (zadanie dodatkowe):
- Uruchom tyle procesów wywołujących funkcję findMinDistance, ile rdzeni ma twój procesor. Każdy powinien dostać odpowiednią część zadania - podzbiór osób.
- Porównaj czas obliczeń.
W tej części trzeba będzie skorzystać z maszyn w laboratorium.
- uruchom węzeł erlanga, spróbuj połączyć się z węzłem uruchomionym przez prowadzącego
- przyda się funkcja
net_adm:ping(NodeName)
orazBIF nodes()
.
- przyda się funkcja
- napisz… szczegóły na laboratorium…
- Zaimplementuj moduł
pollution_server
, który będzie startował proces obsługujący funkcjonalność modułupollution
. Powinien działać analogicznie do serwera zmiennej globalnej - o bogatszej funkcjonalności. - Dodatkowe funkcje eksportowane:
start/0
istop/0
. - Dodatkowa funkcja:
init/0
, która będzie wykonywana już w kontekście nowego procesu. - Serwer powinien dostarczyć funkcje analogiczne do modułu
pollution
- ale każda z nich będzie miała o jeden argument mniej. Serwer ma wołać funkcje z modułupollution
.
- Dokończ moduł
pollution_server
- Przetestuj moduły
pollution
ipollution_server
.