2013-06-27 95 views
1

好友,
我有一个关于Erlang gen_server的问题。
代码集是在这里:
文件:akita_cluster_info.erlerlang gen_server进程不会退出时它不会陷阱退出

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

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

文件: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{}}. 

从外壳的输出是这样的:
不要陷阱出口:

ESHELL V5.9.1(用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} }
{OK,< 0.48.0>}
(秋田@浩)2>

阱出口:

ESHELL V5.9.1(与中止^ G)
(秋田@hao)1> akita_cluster_info:start_link()。
DIC:[{ '$祖先',[< 0.50.0>]},{ '$ initial_call',{akita_collector_local,INIT,1}}] 终止原因:正常
接收信息:{init_dets,{秋田@浩,OK}}
接收信息:{collector_close,{秋田@浩,正常}}
{OK,< 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:多重呼叫

+0

你能发布你在shell上做的测试的细节吗? – Isac

回答

3

我认为这是因为RPC产生的过程:与原因正常多呼叫退出

当两个进程的链接,如果其中一人的原因正常退出,另外一个没有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)退出。