【发布时间】:2012-11-06 20:31:12
【问题描述】:
以下代码同样来自rabbitmq's supervisor2.erl。该代码的功能是杀死主管的孩子,每一个孩子:
监控子发送可捕获的退出信号
启动计时器
如果计时器到达,发送一个不可捕获的退出信号(kill)。
关于EXIT and DOWN signal.的问题
如果child没有捕获exit信号,supervisor会收到2个信号,首先是exit信号,然后是DOWN信号,对吗?信号序列是否得到严格保证?
如果孩子捕获exit信号,监督者只会收到1个信号,只是down信号,是吗?
terminate_simple_children(Child, Dynamics, SupName) ->
Pids = dict:fold(fun (Pid, _Args, Pids) ->
erlang:monitor(process, Pid),
unlink(Pid),
exit(Pid, child_exit_reason(Child)),
[Pid | Pids]
end, [], Dynamics),
TimeoutMsg = {timeout, make_ref()},
TRef = timeout_start(Child, TimeoutMsg),
{Replies, Timedout} =
lists:foldl(
fun (_Pid, {Replies, Timedout}) ->
{Reply, Timedout1} =
receive
TimeoutMsg ->
Remaining = Pids -- [P || {P, _} <- Replies],
[exit(P, kill) || P <- Remaining],
receive {'DOWN', _MRef, process, Pid, Reason} ->
{{error, Reason}, true}
end;
{'DOWN', _MRef, process, Pid, Reason} ->
{child_res(Child, Reason, Timedout), Timedout};
{'EXIT', Pid, Reason} -> %%<==== strict signal, first EXIT, then DOWN.
receive {'DOWN', _MRef, process, Pid, _} ->
{{error, Reason}, Timedout}
end
end,
{[{Pid, Reply} | Replies], Timedout1}
end, {[], false}, Pids),
timeout_stop(Child, TRef, TimeoutMsg, Timedout),
ReportError = shutdown_error_reporter(SupName),
[case Reply of
{_Pid, ok} -> ok;
{Pid, {error, R}} -> ReportError(R, Child#child{pid = Pid})
end || Reply <- Replies],
ok.
【问题讨论】:
标签: erlang rabbitmq exit erlang-supervisor