Erlang主管不重新启动孩子

我正在尝试了解erlang主管。 我有一个简单的printer process ,每3秒打印一次hello。 如果发生任何异常,我也有一个主管必须重新启动printer process

这是我的代码:

test.erl:

-module(test).
-export([start_link/0]).    

start_link() ->
    io:format("started~n"),
    Pid = spawn_link(fun() -> loop() end),
    {ok, Pid}.    

loop() ->
    timer:sleep(3000),
    io:format("hello~n"),
    loop().

test_sup.erl:

-module(test_sup).
-behaviour(supervisor).

-export([start_link/0]).
-export([init/1]).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).    

init(_Args) ->
    SupFlags = #{strategy => one_for_one, intensity => 1, period => 5},    
    ChildSpecs = [#{id => test,
                    start => {test, start_link, []},
                    restart => permanent,
                    shutdown => brutal_kill,
                    type => worker,
                    modules => [test]}],    
    {ok, {SupFlags, ChildSpecs}}.

现在我运行这个程序并使用test_sup:start_link().启动监督器test_sup:start_link(). 命令,并在几秒钟后,我提出了一个例外。 为什么管理员不重新启动printer process

这里是shell输出:

1> test_sup:start_link().
started
{ok,<0.36.0>}
hello
hello
hello
hello          
2> erlang:error(err).

=ERROR REPORT==== 13-Dec-2016::00:57:10 ===
** Generic server test_sup terminating 
** Last message in was {'EXIT',<0.34.0>,
                           {err,
                               [{erl_eval,do_apply,6,
                                    [{file,"erl_eval.erl"},{line,674}]},
                                {shell,exprs,7,
                                    [{file,"shell.erl"},{line,686}]},
                                {shell,eval_exprs,7,
                                    [{file,"shell.erl"},{line,641}]},
                                {shell,eval_loop,3,
                                    [{file,"shell.erl"},{line,626}]}]}}
** When Server state == {state,
                            {local,test_sup},
                            one_for_one,
                            [{child,<0.37.0>,test,
                                 {test,start_link,[]},
                                 permanent,brutal_kill,worker,
                                 [test]}],
                            undefined,1,5,[],0,test_sup,[]}
** Reason for termination == 
** {err,[{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]},
         {shell,exprs,7,[{file,"shell.erl"},{line,686}]},
         {shell,eval_exprs,7,[{file,"shell.erl"},{line,641}]},
         {shell,eval_loop,3,[{file,"shell.erl"},{line,626}]}]}
** exception error: err

当你执行erlang:error(err). ,你正在杀死调用进程,你的shell。

正如您使用start_link启动主管,它也会被终止,并且循环也会被终止。

外壳会自动重启(感谢一些主管),但是没有人重启你的测试管理器,它不能重启循环。

要做这个测试你应该这样做:

在模块测试中:

start_link() ->
    Pid = spawn_link(fun() -> loop() end),
    io:format("started ~p~n",[Pid]),
    {ok, Pid}.

你会得到一个提示:

started <0,xx,0>

其中<0,xx,0>是循环pid,并且可以在shell中调用

exit(pid(0,xx,0), err).

只杀死循环。


以下是您用文件创建的体系结构:

test_sup (supervisor)
  ^
  |
  v
 test (worker)

然后,通过在shell中调用start_link()来启动您的主管。 这创建了另一个双向链接:

shell
  ^
  |
  v
test_sup (supervisor)
  ^
  |
  v
 test (worker)

通过双向链接,如果任何一方死亡,另一方死亡。

当你运行erlang:error ,你在shell中导致错误!

你的shell与你的主管联系在一起,所以Erlang杀死了主管。 通过连锁反应,你的工作人员也会死亡。

我认为你打算把错误情况发送给你的工作者而不是shell:

  • 确定你的工人的Pid: supervisor:which_children
  • 打电话给erlang:exit(Pid, Reason)在工作人员的Pid上erlang:exit(Pid, Reason)
  • 链接地址: http://www.djcxy.com/p/6519.html

    上一篇: Erlang supervisor does not restart child

    下一篇: Erlang supervisor dynamic change to restart intensity