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'


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow