erlang Simple_one_for_one只有在指定SHUTDOWN策略为brutal_kill时才能终止?

mpgws1up  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(199)

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.

flseospp

flseospp1#

对不起,我的结果错了。
要说明的是:

  1. brutal_kill策略立即终止子进程。
    1.如果simple_one_for_one的关闭策略是整数超时,则将调用terminate方法。子进程必须在其init回调中声明process_flag(trap_exit, true)
    仅供参考,Erlang文档手册:
    如果gen_server是监督树的一部分,并且由其监督者命令终止,则在以下条件适用的情况下,将使用Reason=shutdown调用此函数:
    gen_server已设置为捕获退出信号,并且在Supervisor的子规范中定义的关闭策略是一个整数超时值,而不是brutate_kill。
xxls0lw8

xxls0lw82#

无论关闭策略如何,简单一对一管理程序的动态创建的子进程都不会显式终止,但当管理程序终止时(即,当接收到来自父进程的退出信号时),子进程预期会终止。
请注意,这不再是真的。自Erlang/OTP R15 A以来,动态子are explicitly terminated按照关机策略。

相关问题