2016-12-12 144 views
0

我想了解erlang主管。我有一个简单的printer process,每3秒打印一次hello。如果发生任何异常,我也有一位主管必须重新启动printer processErlang主管不重新启动孩子

这里是我的代码:

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().命令启动的主管人员和一个后几秒钟,我提出一个例外。为什么主管不重新启动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 
+0

的[无法产卵从壳一个Erlang监]可能的复制(http://stackoverflow.com/questions/2785692/cannot-spawn-an-erlang-supervisor-from-the-shell) –

回答

3

当您执行erlang:error(err).,你杀调用过程中,你的shell。

正如你已经使用start_link来启动监督者,它也被杀死,并且循环也是。

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

为了使这个测试,你应该做的:

在模块测试:

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

你会得到一个提示:

started <0,xx,0> 

其中<0,xx,0>是回路PID,并在壳你可以打电话

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

只能杀死循环。

2

这里是您与您的文件创建的架构:

test_sup (supervisor) 
^
    | 
    v 
test (worker) 

然后,通过在shell调用start_link()开始你的上司。这将创建另一个双向链接:

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

与双向链接,如果任何一方死亡,另一方被杀害。

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

你的shell与你的主管有关,所以Erlang杀死了主管作为回应。通过连锁反应,你的工作人员也会死亡。

我想你打算发送错误条件,你的工人,而不是外壳:

  1. 确定你的工人的PID:在工人进程的PID supervisor:which_children
  2. 呼叫erlang:exit(Pid, Reason)