3

我一直在尝试使用 erlang:monitor/2 监控 gen_server。不幸的是,每次我尝试这个时,Erlang shell 都会进入一个无限循环。

这是我为测试它而编写的测试程序。

-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 行更改为 erlang:monitor(spawn(fun() -> ok end)) 之类的东西时,上面的代码可以作为故意的。

有人可以告诉我我做错了什么吗?是否只能通过主管监控 gen_server 进程?

谢谢

4

1 回答 1

4

这不是一个无限循环(Erlang 中根本没有循环),你的 shell 只是阻塞接收,直到 gen_server 因某种原因死亡。如果您希望 shell 立即返回,只需生成一个额外的进程来进行监控。它不必是 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 回答