Erlang gen_server进程在没有陷阱退出时不会退出

时间:2013-06-27 14:30:59

标签: linux erlang gen-server

哥们,
我对Erlang gen_server有疑问 代码插曲在这里:
文件:akita_cluster_info.erl

start_link() ->
    gen_server:start_link({global, ?MODULE}, ?MODULE, [], []).

init([]) ->
    c:nl(akita_collector_local),
    rpc:multicall(akita_collector_local, start, []),
    {ok, #state{}}.  

file:akita_collector_local.erl

start() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). 

init([]) ->
    %%process_flag(trap_exit, true),
    init_dets_file(),
    io:format("dic: ~w~n", [get()]),
    {ok, #state{}}.  

shell的输出如下:
不要陷阱退出:

  

Eshell V5.9.1(以^ G中止)
  (秋田@浩)1> akita_cluster_info:START_LINK()
。   dic:[{'$ ancestors',[< 0.50.0>]},{'$ initial_call',{akita_collector_local,init,1}}]
  收到信息:{init_dets,{akita @ hao,ok}}
  {确定,< 0.48.0>}
  (秋田@浩)2 - ;

陷阱退出:

  

Eshell V5.9.1(以^ G中止)
  (秋田@浩)1> akita_cluster_info:START_LINK()
。   dic:[{'$ ancestors',[< 0.50.0>]},{'$ initial_call',{akita_collector_local,init,1}}]   原因终止:正常
  收到信息:{init_dets,{akita @ hao,ok}}
  收到信息:{collector_close,{akita @ hao,normal}}
  {确定,< 0.48.0>}
  (秋田@浩)2 - ;

process_flag(trap_exit, true) 未注释时, akita_collector_local gen_server进程将立即退出,因为其父进程(在rpc:multicall中生成)将终止。我知道这是正常的。
有什么奇怪的是,当没有process_flag(trap_exit, true)时, akita_collector_local gen_server进程可以存活 !!由于它不能捕获出口,它应该立即退出。 (这个理论是正确的,我在Erlang shell中测试过)。但是为什么在这种情况下gen_server进程不会退出。我不知道。
你能帮助我吗?非常感谢。
BRS,

ps:我觉得棘手的部分可能在于 rpc:multicall

1 个答案:

答案 0 :(得分:3)

我认为这是因为rpc:multicall中生成的流程退出的原因是 正常

如果链接了两个进程,如果其中一个进程以 正常 的原因退出,则另一个没有trap_exit的进程将不存在。

process_flag(trap_exit, true) 没有评论时,在gen_server.erl的源代码中,我们可以看到:

346 decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, Hib) ->
347     case Msg of
348         {system, From, Req} ->
349             sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
350                 [Name, State, Mod, Time], Hib);
351         {'EXIT', Parent, Reason} ->
352                 terminate(Reason, Name, Msg, Mod, State, Debug);
只要其父(生成gen_server的进程)退出,

Gen_server将自动终止