3

erlang:monitor/2 を使用して gen_server を監視しようとしています。残念ながら、これを試みるたびに、Erlang シェルは無限ループに陥ります。

これをテストするために書いたテストプログラムを次に示します。

-module(testmon).

-compile(export_all).

start() ->
    {ok,Proc} = gen_server:start(calc,[],[]),
    erlang:monitor(process,Proc),
    receive
        {'DOWN', Ref, process, Pid,  normal} -> 
            io:format("~p said that ~p died by natural causes~n",[Ref,Pid]);
        {'DOWN', Ref, process, Pid,  Reason} ->
            io:format("~p said that ~p died by unnatural causes~n~p",[Ref,Pid,Reason])
    end.

上記のコードを使用して、この spawn(fun() -> ok end) (6 行目と 7 行目を変更) のようなものを監視すると、上記のコードは次のように機能します。意図されました。

誰かが私が間違っていることを教えてもらえますか? スーパーバイザ経由で gen_server プロセスを監視することしかできませんか?

ありがとうございました

4

1 に答える 1

4

これは無限ループではありません (Erlang にはループはまったくありません)。シェルは、何らかの理由で gen_server が停止するまで受信をブロックします。シェルをすぐに返したい場合は、監視を行うための追加のプロセスを生成するだけです。gen_supervisor である必要はありません。別のプロセスのコードは意図したとおりに動作する必要があります。

これは次のようになります。

-module(testmon).

-compile(export_all).

start() ->
    {ok,Proc} = gen_server:start(calc,[],[]),
    spawn(?MODULE, monitor, [Proc]).

monitor(Proc) ->
    erlang:monitor(process,Proc),
    receive
        {'DOWN', Ref, process, Pid,  normal} -> 
            io:format("~p said that ~p died by natural causes~n",[Ref,Pid]);
        {'DOWN', Ref, process, Pid,  Reason} ->
            io:format("~p said that ~p died by unnatural causes~n~p",[Ref,Pid,Reason])
    end.
于 2012-04-19T21:06:38.643 に答える