美好的一天,我为我的小服务设置了以下设置:
-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).
....
这是repl摘录:
(emacs@rover)83> mrtask_net:start().
<0.445.0>
(emacs@rover)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
(emacs@rover)85>
如您所见,停止进程会产生错误,但进程正在停止。 这个错误意味着什么以及如何使事情变得干净?
答案 0 :(得分:20)
不是Erlang程序员而只是来自exit
(here)的文档,我会说,exit
需要一个进程ID作为第一个参数,而你正在传递一个原子(?SERVER
)到它。
尝试
exit(whereis(?SERVER), ok).
而是(whereis
返回与名称相关联的进程ID,请参阅here)
答案 1 :(得分:4)
您需要将调用更改为exit/2
,如@MartinStettner所指出的那样。无论如何,该过程停止的原因是您已使用spawn_link
启动它。然后,您的进程将链接到shell进程。当您调用mrtask_net:stop()
时,错误导致shell进程崩溃,从而导致进程在链接时崩溃。然后会自动启动一个新的shell进程,以便您可以继续使用shell。您通常希望使用spawn_link
启动服务器,但是当您从shell测试它们时它们可能会导致混淆,并且它们只是“发生”死亡。
答案 2 :(得分:2)
我建议你坚持使用OTP。它确实给你带来了很多好处(我几乎无法想象OTP无益的情况)。
所以,如果你想在OTP中停止进程,你应该为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!"}),
您可以在此处找到更多相关信息:http://www.erlang.org/doc/man/gen_server.html