2011-11-01 18 views
10

Buenos días, he siguiente configuración para mi pequeño servicio:Erlang. Forma correcta para detener el proceso

-module(mrtask_net). 

-export([start/0, stop/0, listen/1]). 

-define(SERVER, mrtask_net). 

start() -> 
    Pid = spawn_link(fun() -> ?MODULE:listen(4488) end), 
    register(?SERVER, Pid), 
    Pid. 

stop() -> 
    exit(?SERVER, ok). 

.... 

Y aquí está el extracto repl:

([email protected])83> mrtask_net:start(). 
<0.445.0> 
([email protected])84> mrtask_net:stop(). 
** exception error: bad argument 
    in function exit/2 
     called as exit(mrtask_net,ok) 
    in call from mrtask_net:stop/0 
([email protected])85> 

Como se puede ver, el proceso de detener produce el error, el proceso de se detiene sin embargo. ¿Qué significa este error y cómo limpiarlo?

Respuesta

20

Al no ser un programador de Erlang y sólo de la documentación de exit (here), diría, que exit requiere un identificador de proceso como primer argumento, mientras que usted está pasando un átomo (?SERVER) a la misma.

Trate

exit(whereis(?SERVER), ok). 

lugar (whereis devuelve el identificador de proceso asociado a un nombre, ver here)

+6

1 Ser capaz de leer la documentación puede ser tan valioso como saber un idioma al revés. – BRampersad

4

Es necesario cambiar la llamada a exit/2 como @MartinStettner ha señalado. La razón por la que el proceso se detiene de todos modos es porque la ha iniciado con spawn_link. Su proceso está vinculado al proceso de shell. Cuando llamó al mrtask_net:stop(), el error provocó que el proceso del shell se bloquee, lo que provocó que el proceso se bloquee al vincularse. Un nuevo proceso de shell se inicia automáticamente para que pueda seguir trabajando con el shell. Por lo general, desea iniciar sus servidores con spawn_link, pero puede causar confusión cuando los prueba desde el shell y simplemente "mueren".

2

Le sugiero que se quede con OTP. Realmente te da toneladas de ventajas (casi no puedo imaginar el caso donde OTP no se beneficia).

lo tanto, si desea detener el proceso de OTP que debe hacer algo como esto por gen_server:

% process1.erl 
% In case you get cast message {stopme, Message} 
handle_cast({stopme, Message}, State) -> 
    % you will stop 
    {stop, normal, State} 
handle_cast(Msg, State) -> 
    % do your stuff here with msg 
    {noreply, State}. 

% process2.erl 
% Here the code to stop process1 
gen_server:cast(Pid, {stopme, "It's time to stop!"}), 

Más de ello se puede encontrar aquí: http://www.erlang.org/doc/man/gen_server.html

Cuestiones relacionadas