0xA*_*xAX 3 erlang erlang-otp erlang-supervisor
我有根管理员创建其他主管:
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
RestartStrategy = {one_for_one, 5, 600},
ListenerSup =
{popd_listener_sup,
{popd_listener_sup, start_link, []},
permanent, 2000, supervisor, [popd_listener]},
Children = [ListenerSup],
{ok, {RestartStrategy, Children}}.
Run Code Online (Sandbox Code Playgroud)
我有gen_server - 监听器.popd_listener_sup当主管创建时,如何与主管一起运行此gen_server ?
谢谢.
Yas*_*aev 12
-module(root_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1, shutdown/0]).
start_link() ->
supervisor:start_link({local,?MODULE}, ?MODULE, []).
init(_Args) ->
RestartStrategy = {one_for_one, 10, 60},
ListenerSup = {popd_listener_sup,
{popd_listener_sup, start_link, []},
permanent, infinity, supervisor, [popd_listener_sup]},
Children = [ListenerSup],
{ok, {RestartStrategy, Children}}.
% supervisor can be shutdown by calling exit(SupPid,shutdown)
% or, if it's linked to its parent, by parent calling exit/1.
shutdown() ->
exit(whereis(?MODULE), shutdown).
% or
% exit(normal).
Run Code Online (Sandbox Code Playgroud)
如果子进程是另一个主管,那么Shutdown应该将子规范设置为infinity给子树足够的时间来关闭,并且Type应该设置为supervisor,这就是我们所做的.
-module(popd_listener_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
start_link() ->
supervisor:start_link({local,?MODULE}, ?MODULE, []).
init(_Args) ->
RestartStrategy = {one_for_one, 10, 60},
Listener = {ch1, {ch1, start_link, []},
permanent, 2000, worker, [ch1]},
Children = [Listener],
{ok, {RestartStrategy, Children}}.
Run Code Online (Sandbox Code Playgroud)
在这里,孩子规格,我们设置的值Shutdown来2000.整数超时值意味着主管将通过调用告诉子进程终止exit(Child,shutdown),然后等待从子进程返回原因的退出信号.
-module(ch1).
-behaviour(gen_server).
% Callback functions which should be exported
-export([init/1]).
-export([handle_cast/2, terminate/2]).
% user-defined interface functions
-export([start_link/0]).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
init(_Args) ->
erlang:process_flag(trap_exit, true),
io:format("ch1 has started (~w)~n", [self()]),
% If the initialization is successful, the function
% should return {ok,State}, {ok,State,Timeout} ..
{ok, []}.
handle_cast(calc, State) ->
io:format("result 2+2=4~n"),
{noreply, State};
handle_cast(calcbad, State) ->
io:format("result 1/0~n"),
1 / 0,
{noreply, State}.
terminate(_Reason, _State) ->
io:format("ch1: terminating.~n"),
ok.
Run Code Online (Sandbox Code Playgroud)
从Erlang/OTP文档:
如果gen_server是监督树的一部分并且由其主管命令终止,则在满足以下条件时
Module:terminate(Reason, State)将调用该函数Reason=shutdown:
- 在
gen_server已设置为捕获退出信号,并且- 监督者的子规范中定义的关闭策略
是整数超时值,而不是
brutal_kill.
这就是为什么我们叫erlang:process_flag(trap_exit, true)在Module:init(Args).
启动根管理员:
1> root_sup:start_link().
ch1 has started (<0.35.0>)
{ok,<0.33.0>}
Run Code Online (Sandbox Code Playgroud)
在我们的案例中,根管理器运行并自动启动其子进程,子管理程序.儿童监督员反过来开始其子过程; 在我们的案例中,我们只有一个孩子ch1.
让我们ch1评估正常代码:
2> gen_server:cast(ch1, calc).
result 2+2=4
ok
Run Code Online (Sandbox Code Playgroud)
现在一些不好的代码:
3> gen_server:cast(ch1, calcbad).
result 1/0
ok
ch1: terminating.
=ERROR REPORT==== 31-Jan-2011::01:38:44 ===
** Generic server ch1 terminating
** Last message in was {'$gen_cast',calcbad}
** When Server state == []
** Reason for termination ==
** {badarith,[{ch1,handle_cast,2},
{gen_server,handle_msg,5},
{proc_lib,init_p_do_apply,3}]}
ch1 has started (<0.39.0>)
4> exit(normal).
ch1: terminating.
** exception exit: normal
Run Code Online (Sandbox Code Playgroud)
您可能会看到儿童ch1主管重新启动子进程popd_listener_sup(通知ch1 has started (<0.39.0>)).
由于我们的shell和root管理程序是双向链接的(调用supervisor:start_link,而不是supervisor:start根管理程序功能start_link/0),exit(normal)导致根管理程序关闭,但其子进程有一些时间来清理.
| 归档时间: |
|
| 查看次数: |
4448 次 |
| 最近记录: |