我正在尝试创建一个处理添加动态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 shell中:
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}]}}}
感谢任何帮助/解释/解决方案, /秒。
答案 0 :(得分:2)
如果一个策略只有一个,请阅读OTP Doc:,在start_child函数中,您可以将参数作为子项的子start_link函数的列表传递。
答案 1 :(得分:2)
当您使用simple_one_for_one
时,所有孩子都将使用相同的ChildSpec,init/1
回调中提供的那个和此初始化只能返回一个 ChildSpec。同样在这种情况下,supervisor:start_child/2
的第二个参数必须是一个列表,不一个ChildSpec。此列表是附加参数的列表,它附加到默认ChildSpec中给出的参数列表中,它是在调用子函数的start函数时使用的组合参数列表。这就是simple_one_for_one
个孩子都可以使用相同的ChildSpec并且仍然能够获得特定参数的方式。
在您的情况下,由于ChildSpec中有一个空列表,并且您使用空列表调用start_child/2
,启动函数的参数总数为0
。这与您start_link/0
函数的定义方式相匹配。
另一种方法是使用one_for_one
并使用自己的ChildSpec启动每个孩子。更复杂但也更通用。
不幸的是,supervisor:start_child/2
的这种双重用法使其参数不一致。