Prozesse starten und Nachrichten senden
Erlang-Prozesse sind extrem leichtgewichtig (Hunderttausende sind normal) und teilen keinen Speicher. Sie kommunizieren per Nachricht mit ! (senden) und receive (empfangen):
echo() ->
receive
{From, Nachricht} ->
From ! {echo, Nachricht},
echo();
stop ->
ok
end.
main(_) ->
Pid = spawn(fun echo/0),
Pid ! {self(), hallo},
receive
{echo, Antwort} -> io:format("Antwort: ~p~n", [Antwort])
after 1000 -> io:format("Timeout~n")
end,
Pid ! {self(), welt},
receive
{echo, A2} -> io:format("Antwort: ~p~n", [A2])
end,
Pid ! stop,
timer:sleep(50),
io:format("lebt noch: ~p~n", [is_process_alive(Pid)]).Ausgabe
Antwort: hallo Antwort: welt lebt noch: false
Zustand in Prozessen
Ein Prozess hält Zustand in den Argumenten seiner Schleife:
zaehler(N) ->
receive
erhoehe -> zaehler(N + 1);
{abfragen, From} -> From ! {stand, N}, zaehler(N);
stop -> ok
end.
main(_) ->
Z = spawn(fun() -> zaehler(0) end),
[Z ! erhoehe || _ <- lists:seq(1, 5)],
Z ! {abfragen, self()},
receive {stand, Stand} -> io:format("Stand: ~p~n", [Stand]) end,
Z ! stop,
Eltern = self(),
Arbeiter = [spawn(fun() -> Eltern ! {ergebnis, I, I * I} end) || I <- lists:seq(1, 5)],
Ergebnisse = [receive {ergebnis, I, Q} -> {I, Q} end || I <- lists:seq(1, length(Arbeiter))],
io:format("~p~n", [lists:sort(Ergebnisse)]),
Viele = [spawn(fun() -> receive stop -> ok end end) || _ <- lists:seq(1, 10000)],
io:format("~p Prozesse gestartet~n", [length(Viele)]),
[P ! stop || P <- Viele],
ok.Ausgabe
Stand: 5
[{1,1},{2,4},{3,9},{4,16},{5,25}]
10000 Prozesse gestartetVerknüpfung, Monitore und Fehler
Prozesse können sich gegenseitig überwachen. Das ist die Grundlage der Fehlertoleranz:
main(_) ->
logger:set_primary_config(level, none), % Absturzberichte unterdrücken
{Pid, Ref} = spawn_monitor(fun() -> exit(kaputt) end),
receive
{'DOWN', Ref, process, Pid, Grund} -> io:format("Prozess endete: ~p~n", [Grund])
end,
process_flag(trap_exit, true),
Kind = spawn_link(fun() -> 1 / hd([0]) end),
receive
{'EXIT', Kind, {badarith, _}} -> io:format("Kind: badarith~n");
{'EXIT', Kind, Anders} -> io:format("Kind: ~p~n", [Anders])
end,
{P2, R2} = spawn_monitor(fun() -> ok end),
receive {'DOWN', R2, process, P2, normal} -> io:format("normal beendet~n") end,
register(meinprozess, spawn(fun() -> receive {Von, ping} -> Von ! pong end end)),
meinprozess ! {self(), ping},
receive pong -> io:format("pong von registriertem Namen~n") end,
io:format("~p~n", [whereis(unbekannt)]).Ausgabe
Prozess endete: kaputt Kind: badarith normal beendet pong von registriertem Namen undefined
Merke
spawnstartet Prozesse,!sendet,receiveempfängt (mitafterals Timeout)- Prozesse teilen keinen Speicher; Zustand lebt in der Schleife des Prozesses
spawn_link,spawn_monitorundtrap_exitüberwachen andere Prozesseregister/2gibt Prozessen Namen
Aufgabe
Schreibe einen Prozess, der Zahlen addiert und die Summe auf Anfrage zurückschickt.