主管是一种 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]}}.
Run Code Online (Sandbox Code Playgroud)
上面的代码将调用孩子的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).
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
这两个mod_zytm_sup
和mod_zytm_room_sup
是一个系统的监督树的一部分,mod_zytm_sup
调用mod_zytm_room_sup
创建或接近mod_zytm_room过程。
抱歉,我得到了错误的结果。
为了明确起见:
brutal_kill
策略立即杀死子进程。terminate
如果 simple_one_for_one 的关闭策略是整数超时,则将调用该方法。子级必须process_flag(trap_exit, true)
在其init
回调中声明。仅供参考,Erlang 文档手册:
如果 gen_server 是监督树的一部分,并且被其监督者命令终止,则如果满足以下条件,则将使用 Reason=shutdown 调用此函数:
gen_server 已设置为捕获退出信号,并且主管子规范中定义的关闭策略是整数超时值,而不是brutal_kill。