2011-11-01 14 views
10

Buon giorno, ho seguente configurazione per il mio piccolo servizio:Erlang. modo corretto di fermare il processo

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

.... 

Ed ecco l'estratto 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> 

Come si vede, il processo di arresto genera errore, processo si sta fermando però. Cosa significa questo errore e come rendere la cosa pulita?

risposta

20

Non essendo un programmatore di Erlang e proprio dalla documentazione di exit (here), direi, che exit richiede un ID di processo come primo argomento, mentre si sta passando un atomo (?SERVER) ad esso.

Prova

exit(whereis(?SERVER), ok). 

invece (whereis restituisce l'ID di processo associato a un nome, vedere here)

+6

+1 Essere in grado di leggere la documentazione può essere altrettanto prezioso di conoscere una lingua dentro e fuori. – BRampersad

4

È necessario modificare la chiamata a exit/2 come @MartinStettner ha sottolineato. Il motivo per cui il processo si arresta comunque è che è stato avviato con spawn_link. Il tuo processo è quindi collegato al processo di shell. Quando hai chiamato lo mrtask_net:stop() l'errore ha causato l'arresto anomalo del processo della shell, causando l'arresto anomalo del processo durante il collegamento. Un nuovo processo di shell viene quindi avviato automaticamente in modo da poter continuare a lavorare con la shell. Generalmente vuoi avviare i tuoi server con spawn_link ma può causare confusione quando li stai provando dalla shell e loro "capita" di morire.

2

Ti suggerisco di seguire OTP. Ti dà davvero un sacco di vantaggi (non riesco a immaginare il caso in cui l'OTP non apporti benefici).

Quindi, se si vuole fermare il processo in OTP si dovrebbe fare qualcosa di simile per 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!"}), 

più su di esso si possono trovare qui: http://www.erlang.org/doc/man/gen_server.html

Problemi correlati