1

私はErlangを初めて使用するので、お手柔らかにお願いします。

たとえば、erlang で receive ステートメントがどのように実行されるかについて、私は混乱しています。

loop() ->
   receive
       MessageA -> handlerA();
       MessageB -> handlerB()
   end

MessageA が受信され、handlerA が実行された場合、しばらくして MessageB がプロセスの受信ボックスに受信された場合、handlerB は実行されますか?

receive ステートメントを再実行するために再帰するコードがたくさんあるので、そうではないと思います。

loop() ->
   receive
       MessageA -> 
          handlerA(),
          loop();
       MessageB -> 
          handlerB(),
          loop()
   end

しかし、messageA のハンドラーに次のような別の receive ステートメントが含まれている場合、ここに問題があります。

loop() ->
   receive
       MessageA -> 
          loop2(),
       MessageB -> 
          handlerB(),
          loop()
   end

 loop2() ->
   receive
      MessageC ->
          handlerC()
          loop2()
      MessageD ->
          handlerD()
          loop2()
   end

この場合、MessageA のハンドラに入ると、MessageB を扱えないということでしょうか?

どうすればこれを解決できますか?MessageB のハンドラを loop2 に入れて?特に複数のレベルの receive ステートメントがある場合、これはあまり優雅に見えません。

これを行うより良い方法はありますか?

4

2 に答える 2

4

以下のコードは「単一のメッセージを受信して​​実行する」という意味なので、複数受信したい場合はループする必要があります。Erlang でこれを行う典型的な方法は、自分自身を末尾呼び出しすることです。

loop() ->
   receive
       MessageA -> handlerA();
       MessageB -> handlerB()
   end

最後の例では、A が別の状態に変化するのに対し、B は同じ状態のままである、ある種のステート マシンがあるように見えます。C および D メッセージを期待している状態にあるときに、A メッセージを受信できなくなることは必ずしも問題ではありませんが、問題のドメインによって異なります。

于 2015-09-02T09:08:28.830 に答える