1

次のコードもrabbitmq's supervisor2.erl. コードの機能は、すべての子に対して、スーパーバイザーの子を殺すことです。

  1. 子を監視して、トラップ可能な終了信号を送信します

  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

ここであなたが混乱していることが2つあります:

  • まず、出口をトラップしているのは子ですが、スーパーバイザー コードを見ています。子プロセスが終了シグナルを処理しても、スーパーバイザには直接影響しません。
  • kill終了シグナルはトラップできません。それはいつも子供を殺します。

supervisor2子供にモニターを持っています。これは、'DOWN'メッセージの取得が保証されていることを意味し、このコードはその種類のメッセージの取得に関心があります。supervisor2トラップ出口もある場合は'EXIT'、さらにメッセージを取得します。

于 2012-11-19T11:07:09.757 に答える