4

動的gen_serversの追加を処理するスーパーバイザーを作成しようとしています。何かが失敗している理由で、私は本当に何がわからない。

-module(supervisor_mod).
-behaviour(supervisor).

-export([start_link/0, add_child/1]).
-export([init/1]).

start_link() ->
    Pid=supervisor:start_link({local, ?MODULE} , ?MODULE, []),
    {ok,Pid}.

init(_Args) ->
    {ok, {{simple_one_for_one, 10, 60},
          [{example_proc, {example_proc, start_link, []},
            permanent, brutal_kill, worker, [example_proc]}]}}.

add_child(Name)->                                                                        
    supervisor:start_child(supervisor_mod,
                           {example_proc, {example_proc, start_link, []},
                            permanent, brutal_kill, worker, [example_proc]}).

-module(example_proc).
-behaviour(gen_server).

-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2]).

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

init(Args) ->
    io:format("~p (~p) started...~n", [Args, self()]),
    {ok, []}.

handle_call(alloc, From, State) ->
    {reply, From, State}.

handle_cast({free, _Ch}, State) ->
    {noreply, State}.

erlシェルで:

Eshell V5.8.2  (abort with ^G)
1> supervisor_mod:start_link().
{ok,{ok,<0.33.0>}}
2> supervisor_mod:add_child(aa).
{error,{'EXIT',{badarg,[{erlang,apply,
                                [example_proc,start_link,
                                 {example_proc,{example_proc,start_link,[]},
                                               permanent,brutal_kill,worker,
                                               [example_proc]}]},
                        {supervisor,do_start_child_i,3},
                        {supervisor,handle_call,3},
                        {gen_server,handle_msg,5},
                        {proc_lib,init_p_do_apply,3}]}}}

ヘルプ/説明/解決策をいただければ幸いです、/s。

4

2 に答える 2

3

OTPドキュメントを読む: 1つの戦略に対する単純なものの場合、start_child関数で、子の子start_link関数のリストとして引数を渡すことができます。

于 2012-06-20T13:24:17.410 に答える
3

すべての子を使用simple_one_for_oneする場合、同じChildSpecを使用します。init/1コールバックで指定されたものとこの初期化では、 1つのChildSpecのみを返すことができます。また、この場合、の2番目の引数は、 ChildSpecsupervisor:start_child/2ではなくリストである必要があります。このリストは、デフォルトのChildSpecで指定された引数リストに追加される追加の引数のリストであり、子のstart関数を呼び出すときに使用されるのはこの結合された引数リストです。これは、すべての子が同じChildSpecを使用し、それでも特定の引数を取得できる方法です。simple_one_for_one

あなたの場合、ChildSpecに空のリストがあり、空のリストで呼び出したstart_child/2ので、start関数への引数の総数はでした0start_link/0これは、関数の定義方法と一致しました。

one_for_one別の方法は、各子を独自のChildSpecで使用して開始することです。より複雑ですが、より用途が広いです。

残念ながら、この二重使用によりsupervisor:start_child/2、その議論に一貫性がなくなりました。

于 2012-06-20T13:34:19.343 に答える