如果指定SHUTDOWN策略为brutal_kill,则只能终止Simple_one_for_one?

时间:2013-05-22 14:05:52

标签: erlang otp

主管是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_supmod_zytm_room_sup都是系统监督树的一部分,mod_zytm_sup调用mod_zytm_room_sup来创建或关闭mod_zytm_room流程。

2 个答案:

答案 0 :(得分:4)

抱歉,我的结果错了。

说清楚:

  1. brutal_kill策略立即杀死子进程。
  2. 如果simple_one_for_one的关闭策略是整数超时,则将调用terminate方法。孩子必须在process_flag(trap_exit, true)回调中声明init
  3. 仅供参考,Erlang doc手册:

      

    如果gen_server是监督树的一部分并且由其命令   主管终止,这个功能将被调用   如果满足以下条件,则原因=关闭:

         

    gen_server已设置为捕获退出信号,并关闭   监督者的子规范中定义的策略是   整数超时值,而不是brutal_kill。

答案 1 :(得分:1)

动态创建的一对一简单的子进程 无论关闭策略如何,都不会明确杀死主管, 但应在主管这样做时终止(即 收到来自父进程的退出信号。

请注意,这不再成立。从Erlang / OTP R15A开始,根据关闭策略,动态子级are explicitly terminated