簡體   English   中英

為什么 simple_one_for_one 工人可以共享相同的 Child Spec Id?

[英]Why simple_one_for_one workers can share the same Child Spec Id?

我為名為 band_supervisor 的主管定義 simple_one_for_one 工作規范,子規范 ID 為jam_musician

  init([]) ->
    {ok, {{simple_one_for_one, 3, 60},
    [{jam_musician,
    {musicians, start_link, []},
    temporary, 1000, worker, [musicians]}
    ]}};

音樂家模塊是:

-module(musicians).
-behaviour(gen_server).

-export([start_link/2, stop/1]).
-export([init/1, handle_call/3, handle_cast/2,
handle_info/2, code_change/3, terminate/2]).

-record(state, {name="", role, skill=good}).
-define(DELAY, 750).

start_link(Role, Skill) ->
  gen_server:start_link({local, Role}, ?MODULE, [Role, Skill], []).

stop(Role) -> gen_server:call(Role, stop).

我可以通過以下方式創建許多工人:

3> supervisor:start_child(band_supervisor, [drum, good]).
Musician Arnold Ramon, playing the drum entered the room
{ok,<0.696.0>}
3> supervisor:start_child(band_supervisor, [guitar, good]).
Musician Wanda Perlstein, playing the guitar entered the room
{ok,<0.698.0>}

我注意到所有工人都有相同的兒童規范 ID: jam_musician

你知道其他類型的工人必須有唯一的孩子 id,對嗎?

您很可能將子進程的 start_link 函數(我假設它是一個 gen_server)編寫為:

start_link() ->
    gen_server:start_link({local,Name}, ?MODULE, [], []).

這不僅會調用 init/1 函數,還會使用原子名稱注冊進程。

因此,任何在第二個時刻啟動的新子節點都將嘗試使用第一個子節點已經采用的名稱在 erlang 節點內注冊。

為了避免這種名稱沖突,您應該使用以下內容:

start_link() ->
    gen_server:start_link(?MODULE, [], []).

這樣沒有孩子會有注冊的名字,你就不會發生沖突。

如果你真的需要注冊每個孩子,一個選項可能包括使用gproc

simple_one_for_one主管的子規范標識符將相同,因為只有一種子類型和許多該類型的子實例(工作器)。

supervisor行為文檔

請注意,當重啟策略為simple_one_for_one ,子規范列表必須是只有一個子規范的列表。 (忽略子規范標識符。)然后在初始化階段沒有啟動子進程,但假定所有子進程都使用start_child/2動態啟動。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM