即使我取消注册sts
,我的生成过程也不会停止。如何在不使用gen_server的情况下阻止它?
start() ->
case whereis(sts) of
undefined ->
PidA = spawn(dist_erlang, init,[]),
register(sts, PidA),
{ok,PidA};
_ ->
{ok,whereis(sts)}
end.
stop() ->
case whereis(sts) of
undefined ->
already_stopped;
_ ->
unregister(sts),
stopped,
end.
答案 0 :(得分:4)
使用取消注册不会停止该过程。但是,停止该过程会取消注册。因此,不要在此处使用取消注册,而是使用erlang:exit/2
stop() ->
case whereis(sts) of
undefined ->
already_stopped;
Pid ->
exit(Pid, normal), % Use whatever exit reason you want
stopped
end.
所有这一切,您应该真正使用OTP流程行为(如gen_server),因为它们使流程管理变得更加容易。使用OTP流程,您可以改为call
进程并告诉它停止,这样当您收到回复时它已经停止。否则,您的退出消息可能需要一些时间才能通过。
答案 1 :(得分:1)
unregister
不会停止此过程。它只是删除了进程id和给定原子之间的绑定。
您需要记住stop/0
函数是在调用此函数的进程的上下文中运行的,而不是gen_server本身。实际上(几乎)与某个进程交互的唯一方法就是向它发送消息。因此,您可以像这样实现stop/0
函数:
%% send stop message to `sts` server
stop() ->
gen_server:cast(sts, stop).
%% [...]
handle_cast( OtherCastMessages, State) ->
%% handel other cast messages ;
%% [...] ;
%% handle stop message
handle_cast( _Message = stop, State) ->
{stop,
_Reason = normal,
State}. % return result that stops server
%% [...]
terminate(_Reason = normal, State) ->
%% could do some cleanup in this callback
ok.
因此,要停止服务器,您必须从其中一个行为函数返回特殊元组。您可以阅读有关此here的更多信息。当然,触发一个行为功能,您必须使用gen_server:cast
或gen_server:call
向您的服务器发送消息(或者只发送消息并使用handle_info
处理它)。使用什么是你的决定。最后调用terminate2
(无论哪个回调返回带有stop
atom的元组),您可以在其中对您的州进行一些清理。
当然,您可以在terminate
回调中取消注册您的流程,但是当流程终止时,会自动处理取消注册。