The supervisor is an OTP behavior.
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]}}.
Above code will invoke child's terminate
method.
But if I change the brutal_kill
to an integer timeout (e.g. 6000), the terminate
method was never invoked.
I see an explanation in the Erlang document:
The dynamically created child processes of a simple-one-for-one supervisor are not explicitly killed, regardless of shutdown strategy, but are expected to terminate when the supervisor does (that is, when an exit signal from the parent process is received).
But I cannot fully understand. Is it said that exit(Pid, kill)
can terminate a simple_one_for_one
child spec while exit(Pid, shutdown)
can't ?
===================================update====================================
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.
Both mod_zytm_sup
and mod_zytm_room_sup
are a part of a system supervision tree, mod_zytm_sup
invoke mod_zytm_room_sup
to create or close mod_zytm_room process.
2条答案
按热度按时间flseospp1#
对不起,我的结果错了。
要说明的是:
brutal_kill
策略立即终止子进程。1.如果simple_one_for_one的关闭策略是整数超时,则将调用
terminate
方法。子进程必须在其init
回调中声明process_flag(trap_exit, true)
。仅供参考,Erlang文档手册:
如果gen_server是监督树的一部分,并且由其监督者命令终止,则在以下条件适用的情况下,将使用Reason=shutdown调用此函数:
gen_server已设置为捕获退出信号,并且在Supervisor的子规范中定义的关闭策略是一个整数超时值,而不是brutate_kill。
xxls0lw82#
无论关闭策略如何,简单一对一管理程序的动态创建的子进程都不会显式终止,但当管理程序终止时(即,当接收到来自父进程的退出信号时),子进程预期会终止。
请注意,这不再是真的。自Erlang/OTP R15 A以来,动态子are explicitly terminated按照关机策略。