Ricerca…


Creazione di processi

Creiamo un nuovo processo concorrente chiamando la funzione spawn . La funzione di spawn avrà come parametro una funzione Fun che il processo valuterà. Il valore di ritorno della funzione spawn è l'identificatore del processo creato (pid).

1> Fun = fun() -> 2+2 end.
#Fun<erl_eval.20.52032458>
2> Pid = spawn(Fun).
<0.60.0>

Puoi anche usare spawn/3 per avviare un processo che eseguirà una funzione specifica da un modulo: spawn(Module, Function, Args) .
Oppure usa spawn/2 o spawn/4 modo simile per avviare un processo in un nodo diverso: spawn(Node, Fun) o spawn(Node, Module, Function, Args) .

Messaggio in corso

Due processi di erlang possono comunicare tra loro, noto anche come passaggio di messaggi .
Questa procedura è asincrona nella forma in cui il processo di invio non si interrompe dopo l'invio del messaggio.

Invio di messaggi

Questo può essere ottenuto con il costrutto Pid ! Message , dove Pid è un identificatore di processo valido (pid) e Message è un valore di qualsiasi tipo di dati.

Ogni processo ha una "casella di posta" che contiene i messaggi ricevuti nell'ordine ricevuto. Questa "casella di posta" può essere svuotata con la funzione flush/0 .

Se un messaggio viene inviato a un processo non esistente, il messaggio verrà eliminato senza errori!

Un esempio potrebbe essere simile al seguente, dove self/0 restituisce il pid del processo corrente e pid/3 crea un 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

È anche possibile inviare un messaggio a più processi contemporaneamente, con Pid3!Pid2!Pid1!Msg .

Ricevere messaggi

I messaggi ricevuti possono essere elaborati con il costrutto di receive .

receive
  Pattern1            -> exp11, .., exp1n1;
  Pattern2 when Guard -> exp21, .., exp2n2;
  ...
  Other               -> exp31, .., exp3n3;
  ...
  after Timeout       -> exp41, .., exp4n4
end

Il Pattern verrà confrontato con i messaggi nella "mailbox" a partire dal primo e dal messaggio meno recente.
Se un modello corrisponde, il messaggio corrispondente viene rimosso dalla "cassetta postale" e il corpo della clausola viene valutato.

È anche possibile definire i timeout con il after costrutto.
Un Timeout è il tempo di attesa in millisecondi o l' infinity dell'atomo.

Il valore di ritorno di receive è l'ultimo corpo della clausola valutata.

Esempio (contatore)

Un contatore (molto) semplice con il passaggio del messaggio potrebbe essere simile a quanto segue.

-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.

Interazione con il contatore.

1> C0 = counter0:start().
<0.39.0>
2> C0!increment.
increment
3> C0!increment.
increment

Registra i processi

È possibile registrare un processo (pid) in un alias globale.
Questo può essere ottenuto con la funzione build in register(Alias, Pid) , dove Alias è l'atomo per accedere al processo e Pid è l'id del processo.

L'alias sarà disponibile a livello globale!
È molto facile creare uno stato condiviso, che di solito non è preferibile. ( Vedi anche qui )

È possibile whereis(Alias) registrazione di un processo con un whereis(Alias) unregister(Pid) e ricevere il pid da un alias con whereis(Alias) .

Utilizzare registered() per un elenco di tutti gli alias registrati.

L'esempio registra Atom foo nel pid del processo corrente e invia un messaggio utilizzando l'Atom registrato.

1> register(foo, self()).
true
2> foo ! 'hello world'.
'hello world'


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow