3

band_supervisor という名前の 1 つのスーパーバイザーに対して 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>}

すべてのワーカーが同じ Child 仕様 ID を持っていることに気付きました:jam_musician

他のタイプのワーカーには一意の子 ID が必要ですよね?

4

2 に答える 2

6

ほとんどの場合、子プロセスの start_link 関数を次のように記述しました (これは gen_server であると想定しています)。

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

これは init/1 関数を呼び出すだけでなく、atom Name を使用してプロセスを登録します。

したがって、2 番目の瞬間に開始された新しい子は、最初の子によって既に使用されている名前を使用して、erlang ノード内に登録しようとします。

このような名前の衝突を避けるために、次のようなものを使用する必要があります。

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

子供が登録された名前を持たないように、衝突することはありません。

本当にすべての子を登録する必要がある場合、オプションはgprocの使用に含まれる場合があります。

于 2013-04-02T13:36:38.063 に答える
5

simple_one_for_one子タイプは 1 つしかなく、このタイプの子インスタンス (ワーカー) は多数あるため、スーパーバイザーの子仕様識別子は同じになります。

supervisor動作ドキュメントから:

再始動戦略が の場合、simple_one_for_one子仕様のリストは、子仕様が 1 つだけのリストでなければならないことに注意してください。(子の仕様識別子は無視されます。) 初期化フェーズでは子プロセスは開始されませんが、すべての子は を使用して動的に開始されると想定されますstart_child/2

于 2013-04-03T12:24:37.973 に答える