Erlang 监视gen_服务器

Erlang 监视gen_服务器,erlang,gen-server,monitors,Erlang,Gen Server,Monitors,我一直在尝试使用erlang:monitor/2监视gen_服务器。不幸的是,每次我尝试这样做,Erlang shell都会进入一个无限循环 这是我写的测试程序来测试这个 -module(testmon). -compile(export_all). start() -> {ok,Proc} = gen_server:start(calc,[],[]), erlang:monitor(process,Proc), receive {'DOWN',

我一直在尝试使用erlang:monitor/2监视gen_服务器。不幸的是,每次我尝试这样做,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_服务器进程

谢谢

这不是一个无限循环(Erlang中根本没有循环),您的shell只会阻塞接收,直到gen_服务器因某种原因死亡。 如果希望shell立即返回,只需生成一个额外的进程来进行监视。 它不必是gen_主管,您在单独流程中的代码应该按预期运行

这可能看起来像这样:

-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.

看起来您的代码中出现了复制粘贴错误。另外,在末尾添加“after 1000->timeout”子句可能有助于调试start函数的第1行和第2行??1是纯语法错误..修复:你是正确的,我粘贴代码时不小心弄乱了代码。这就是我最初的打算。谢谢如果启动的
gen_服务器
没有终止,则
接收
将永远等待,除非您按照@Lukas建议添加超时。你说的“无限循环”是什么意思?你的意思是壳永远不会返回吗?无限循环的意思是壳永远不会返回。当我添加after子句时,我确实收到了一个超时。从你们所说的,我可以推断,真正发生的是gen_服务器正确启动,并且由于gen_服务器不会停止,除非它被终止(正常或异常),监视器将永远不会离开接收部分,因此外壳将永远不会返回。我的这些推论正确吗?这就是我最后所做的。谢谢你的澄清。