0

私の作業環境はErlangです。2つの異なる機能を持つプロセスは、異なる機能に2つの受信ブロックを持つことができますか。

receive
....
end.

request()
PID!(message)
%% Can i get the reply back here instead of the receive block above?
4

2 に答える 2

11

はい、あなたは多くのreceive表現を持つことができます。1つが評価されると、最初に一致したメッセージがメッセージキュー/メールボックスから取り出され(名前を選択して)、残りは次のメッセージに残されreceiveます。構文(唯一の方法)を使用したメッセージの送信Pid ! Messageは完全に非同期であり、受信プロセスのメッセージキューの最後にメッセージを追加するだけです。メッセージを受信receiveする唯一の方法です。つまり、メッセージキューからメッセージを取り出します。それらを元に戻すことはできません。

Erlangに渡される組み込みの同期メッセージはありません。2つのメッセージを送信することによるものです。

  • 「要求」プロセスは、受信プロセスにメッセージを送信してreceiveから、応答を待つためにになります。

  • 「受信」プロセス自体がメッセージを取得してreceive処理し、応答メッセージを「要求」プロセスに送り返し、次にreceive座って次のメッセージを待ちます。

プロセス間には固有の接続がないことを忘れないでください。すべての通信は、非同期メッセージ送信とを使用して行われますreceive

したがって、2番目の質問への返信では、式でのみreceive返信を受け取ることができます。それが唯一の方法です!

少し衒学的で申し訳ありませんが、Erlangにはブロックもステートメントもありません。これは関数型言語であり、戻り値が無視されることがある場合でも常に値を返すしかありません。

于 2012-12-02T01:55:22.037 に答える
2

当然のことながら、あなたはそうすることができます。

送信演算子(!)を使用してプロセスに送信されたメッセージを受信します。パターンPatternは、メールボックス内の最初のメッセージと時間順に照合され、次に2番目のメッセージと照合されます。一致が成功し、オプションのガードシーケンスGuardSeqがtrueの場合、対応するBodyが評価されます。一致するメッセージが消費され、メールボックスから削除されますが、メールボックス内の他のメッセージは変更されません。

次のコードはsupervisor2.erlプロジェクトのrabbitmqものです。ネストされたreceiveステートメントも使用します。以下にネストをマークしましたreceive

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 %% attention here 
                          TimeoutMsg ->
                              Remaining = Pids -- [P || {P, _} <- Replies],
                              [exit(P, kill) || P <- Remaining],
                              receive {'DOWN', _MRef, process, Pid, Reason} -> %%attention here
                                      {{error, Reason}, true}
                              end;
                          {'DOWN', _MRef, process, Pid, Reason} ->
                              {child_res(Child, Reason, Timedout), Timedout};
                          {'EXIT', Pid, Reason} -> 
                              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.
于 2012-12-01T21:19:42.633 に答える