Erlang Language
Prozesse
Suche…
Prozesse erstellen
Wir erstellen einen neuen gleichzeitigen Prozess, indem wir die spawn
Funktion aufrufen. Die spawn
Funktion erhält als Parameter eine Funktion Fun
, die der Prozess auswertet. Der Rückgabewert der spawn
Funktion ist die erzeugte Prozesskennung (PID).
1> Fun = fun() -> 2+2 end.
#Fun<erl_eval.20.52032458>
2> Pid = spawn(Fun).
<0.60.0>
Sie können spawn/3
auch verwenden, um einen Prozess zu starten, der eine bestimmte Funktion eines Moduls ausführt: spawn(Module, Function, Args)
.
Oder verwenden Sie spawn/2
oder spawn/4
, um einen Prozess in einem anderen Knoten zu starten: spawn(Node, Fun)
oder spawn(Node, Module, Function, Args)
.
Message Passing
Zwei erlang-Prozesse können miteinander kommunizieren, was auch als Message Passing bezeichnet wird .
Dieses Verfahren ist asynchron in der Form, dass der Sendevorgang nach dem Senden der Nachricht nicht angehalten wird.
Nachrichten senden
Dies kann mit dem Konstrukt Pid ! Message
, wobei Pid
eine gültige Prozesskennung (PID) ist und Message
ein Wert eines beliebigen Datentyps ist.
Jeder Prozess verfügt über ein "Postfach", das die empfangenen Nachrichten in der erhaltenen Reihenfolge enthält. Diese "Mailbox" kann mit der eingebauten flush/0
Funktion geleert werden.
Wenn eine Nachricht an einen nicht vorhandenen Prozess gesendet wird, wird die Nachricht ohne Fehler gelöscht.
Ein Beispiel könnte wie folgt aussehen: self/0
gibt die PID des aktuellen Prozesses zurück und pid/3
erstellt eine PID.
1> Pidsh = self().
<0.32.0>
2> Pidsh ! hello.
hello
3> flush().
Shell got hello
ok
4> <0.32.0> ! hello.
* 1: syntax error before: ’<’
5> Pidsh2 = pid(0,32,0).
<0.32.0>
6> Pidsh2 ! hello2.
hello2
7> flush().
Shell got hello2
ok
Mit Pid3!Pid2!Pid1!Msg
ist es auch möglich, eine Nachricht an mehrere Prozesse gleichzeitig zu senden.
Nachrichten empfangen
Empfangene Nachrichten können mit dem receive
verarbeitet werden.
receive
Pattern1 -> exp11, .., exp1n1;
Pattern2 when Guard -> exp21, .., exp2n2;
...
Other -> exp31, .., exp3n3;
...
after Timeout -> exp41, .., exp4n4
end
Das Pattern
wird mit den Nachrichten in der "Mailbox" verglichen, beginnend mit der ersten und ältesten Nachricht.
Wenn ein Muster übereinstimmt, wird die übereinstimmende Nachricht aus dem "Postfach" entfernt und der Klauselhauptteil ausgewertet.
Es ist auch möglich Timeouts mit zu definieren , die after
konstruieren.
Ein Timeout
ist entweder die Wartezeit in Millisekunden oder das Atom infinity
.
Der Rückgabewert von receive
ist der zuletzt bewertete Klauselkörper.
Beispiel (Zähler)
Ein (sehr) einfacher Zähler mit Nachrichtenweitergabe könnte wie folgt aussehen.
-module(counter0).
-export([start/0,loop/1]).
% Creating the counter process.
start() ->
spawn(counter0, loop, [0]).
% The counter loop.
loop(Val) ->
receive
increment ->
loop(Val + 1)
end.
Interaktion mit dem Schalter.
1> C0 = counter0:start().
<0.39.0>
2> C0!increment.
increment
3> C0!increment.
increment
Prozesse registrieren
Es ist möglich, einen Prozess (PID) für einen globalen Alias zu registrieren.
Dies kann mit der eingebauten register(Alias, Pid)
werden, wobei Alias
das Atom ist, auf das der Prozess zugreifen kann, und Pid
die Prozess-ID ist.
Der Alias ist weltweit verfügbar!
Es ist sehr einfach, einen gemeinsamen Zustand zu erstellen, der normalerweise nicht vorzuziehen ist. ( Siehe auch hier )
Es ist möglich, die Registrierung eines Prozesses mit unregister(Pid)
whereis(Alias)
und die PID von einem Alias mit whereis(Alias)
.
Verwenden Sie registered()
um eine Liste aller registrierten Aliase zu erhalten.
Das Beispiel registriert den Atom-Foo bei der PID des aktuellen Prozesses und sendet eine Nachricht mit dem registrierten Atom.
1> register(foo, self()).
true
2> foo ! 'hello world'.
'hello world'