【问题标题】:erlang's EXIT and DOWN signalerlang的EXIT和DOWN信号
【发布时间】:2012-11-06 20:31:12
【问题描述】:

以下代码同样来自rabbitmq's supervisor2.erl。该代码的功能是杀死主管的孩子,每一个孩子:

  1. 监控子发送可捕获的退出信号

  2. 启动计时器

  3. 如果计时器到达,发送一个不可捕获的退出信号(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


    【解决方案1】:

    您在这里混淆了两件事:

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

    supervisor2 在孩子身上有一个监视器。这意味着它保证会收到'DOWN' 消息,并且此代码关注获取此类消息。如果supervisor2 也捕获了出口,它会另外得到'EXIT' 消息。

    【讨论】:

    • 对于你的最后一段,你确定为什么'DOWN'信号会跟随'EXIT'信号吗?为什么'EXIT'信号不跟随'DOWN'信号?为什么?我在上面的代码中做了一个标记,它显示了严格的信号顺序。
    猜你喜欢
    • 1970-01-01
    • 2011-01-28
    • 2011-04-10
    • 2010-11-16
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 2012-03-14
    • 2015-02-04
    相关资源
    最近更新 更多