1

以下代码也来自rabbitmq's supervisor2.erl. 代码的功能是杀死主管的孩子,为每个孩子:

  1. monitor child 发送一个可捕获的退出信号

  2. 启动计时器

  3. 如果计时器到达,则发送一个无法捕获的退出信号(kill)。

我的问题EXIT and DOWN signal.

如果孩子没有捕获退出信号,主管会收到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.
4

1 回答 1

1

您在这里混淆了两件事:

  • 首先,孩子是一个陷阱出口,但您正在查看主管代码。孩子对退出信号所做的事情不会直接影响主管。
  • 退出kill信号不能被捕获。它总是杀死孩子。

孩子身上supervisor2有显示器。这意味着它保证会收到一条'DOWN'消息,并且此代码关注的是获得那种消息。如果supervisor2也是陷阱出口,它会'EXIT'另外得到消息。

于 2012-11-19T11:07:09.757 回答