Buscar..


Procesos de creación

Creamos un nuevo proceso concurrente llamando a la función spawn . El spawn función tendrá como parámetro de una función de Fun que el proceso va a evaluar. El valor de retorno de la función de spawn es el identificador de proceso creado (pid).

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

También puede usar spawn/3 para iniciar un proceso que ejecutará una función específica desde un módulo: spawn(Module, Function, Args) .
O use spawn/2 o spawn/4 manera similar para iniciar un proceso en un nodo diferente: spawn(Node, Fun) o spawn(Node, Module, Function, Args) .

Paso de mensajes

Dos procesos erlang pueden comunicarse entre sí, lo que también se conoce como paso de mensajes .
Este procedimiento es asíncrono en la forma en que el proceso de envío no se detendrá después de enviar el mensaje.

Enviando mensajes

Esto se puede lograr con el constructo Pid ! Message , donde Pid es un identificador de proceso válido (pid) y Message es un valor de cualquier tipo de datos.

Cada proceso tiene un "buzón" que contiene los mensajes recibidos en el orden recibido. Este "buzón" se puede vaciar con la función de compilación flush/0 .

Si se envía un mensaje a un proceso no existente, el mensaje se descartará sin ningún error.

Un ejemplo podría ser similar al siguiente, donde self/0 devuelve el pid del proceso actual y 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

También es posible enviar un mensaje a varios procesos a la vez, con Pid3!Pid2!Pid1!Msg .

Recibiendo mensajes

Los mensajes recibidos se pueden procesar con la construcción receive .

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

El Pattern se comparará con los mensajes en el "buzón" comenzando con el primer y más antiguo mensaje.
Si un patrón coincide, el mensaje coincidente se elimina del "buzón" y se evalúa el cuerpo de la cláusula.

También es posible definir tiempos de espera con la construcción after .
Un tiempo de Timeout es el tiempo de espera en milisegundos o el átomo infinity .

El valor de retorno de receive es el último cuerpo de la cláusula evaluada.

Ejemplo (Contador)

Un contador (muy) simple con paso de mensajes podría ser similar al siguiente.

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

Interacción con el contador.

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

Procesos de registro

Es posible registrar un proceso (pid) a un alias global.
Esto se puede lograr con la función de creación de register(Alias, Pid) , donde Alias es el átomo para acceder al proceso y Pid es el ID del proceso.

¡El alias estará disponible a nivel mundial!
Es muy fácil crear un estado compartido, que generalmente no es preferible. ( Véase también aquí )

Es posible anular el registro de un proceso con unregister(Pid) y recibir el pid de un alias con whereis(Alias) .

Utilice registered() para obtener una lista de todos los alias registrados.

El ejemplo registra el Atom foo al pid del proceso actual y envía un mensaje utilizando el Atom registrado.

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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow