主管是OTP行为。
init([]) ->
RoomSpec = {mod_zytm_room, {mod_zytm_room, start_link, []},
transient, brutal_kill, worker, [mod_zytm_room]},
{ok, {{simple_one_for_one, 10, 10000}, [RoomSpec]}}.
上面的代码将调用孩子的terminate
方法。
但如果我将brutal_kill
更改为整数超时(例如6000),则永远不会调用terminate
方法。
我在Erlang文档中看到了一个解释:
动态创建的简单一对一子进程 无论关机策略如何,主管都没有被明确杀死, 但预计会在主管做的时候终止(也就是说 收到来自父进程的退出信号。)
但我无法完全理解。是否说exit(Pid, kill)
可以终止simple_one_for_one
子规范,而exit(Pid, shutdown)
则不能?
===================================更新=========== =========================
mod_zytm_room_sup.erl
-module(mod_zytm_room_sup).
-behaviour(supervisor).
-export([start_link/0, init/1, open_room/1, close_room/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
RoomSpec = {mod_zytm_room, {mod_zytm_room, start_link, []},
transient, brutal_kill, worker, [mod_zytm_room]},
{ok, {{simple_one_for_one, 10, 10000}, [RoomSpec]}}.
open_room(RoomId) ->
supervisor:start_child(?MODULE, [RoomId]).
close_room(RoomPid) ->
supervisor:terminate_child(?MODULE, RoomPid).
mod_zytm_room.erl
-module(mod_zytm_room).
-behaviour(gen_server).
-export([start_link/1]).
-export([init/1, handle_cast/2, handle_info/2, handle_call/3, code_change/3, terminate/2]).
start_link(RoomId) ->
gen_server:start_link(?MODULE, [RoomId], []).
init([RoomId]) ->
{ok, []}.
terminate(_, _) ->
error_logger:info_msg("~p terminated:~p", [?MODULE, self()]),
ok.
...other methods ommited.
mod_zytm_sup.erl
-module(mod_zytm_sup).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_cast/2, handle_info/2, handle_call/3, code_change/3, terminate/2]).
start_link() ->
gen_server:start_link(?MODULE, [], []).
init([]) ->
{ok, []}.
%% invoked by an erlang:send_after event.
handle_info({'CLOSE_ROOM', RoomPid}, State) ->
mod_zytm_room_sup:close_room(RoomPid),
{noreply, State}.
...other methods ommited.
mod_zytm_sup
和mod_zytm_room_sup
都是系统监督树的一部分,mod_zytm_sup
调用mod_zytm_room_sup
来创建或关闭mod_zytm_room流程。
答案 0 :(得分:4)
抱歉,我的结果错了。
说清楚:
brutal_kill
策略立即杀死子进程。terminate
方法。孩子必须在process_flag(trap_exit, true)
回调中声明init
。仅供参考,Erlang doc手册:
如果gen_server是监督树的一部分并且由其命令 主管终止,这个功能将被调用 如果满足以下条件,则原因=关闭:
gen_server已设置为捕获退出信号,并关闭 监督者的子规范中定义的策略是 整数超时值,而不是brutal_kill。
答案 1 :(得分:1)
动态创建的一对一简单的子进程 无论关闭策略如何,都不会明确杀死主管, 但应在主管这样做时终止(即 收到来自父进程的退出信号。
请注意,这不再成立。从Erlang / OTP R15A开始,根据关闭策略,动态子级are explicitly terminated。