主管创建多个孩子时的问题
Posted
技术标签:
【中文标题】主管创建多个孩子时的问题【英文标题】:issue when supervisor is creating more than one child 【发布时间】:2016-07-11 12:46:56 【问题描述】:我有一个主管。我从作为 gen_server 的孩子那里得到 child_specs。我首先为一个主管 - 孩子关系写了这个。后来我想让那个主管开始生很多孩子。但是我在子 gen_server 中有一些 ets 表作为状态。因此,当主管试图创建第二个孩子时,它会抛出如下异常:
exception exit: shutdown,
failed_to_start_child,bench_client2,
badarg,
[ets,new,[config,[set,named_table]],[],
bench_client,init,1,
[file,"bench_client.erl",line,59],
gen_server,init_it,6,
[file,"gen_server.erl",line,306],
proc_lib,init_p_do_apply,3,
[file,"proc_lib.erl",line,237]]
我猜测由于 ets 是共享的,当主管转到第二个孩子的 init 函数时,它已经看到了一个 ets 表,因此出现异常但不知道如何解决。不过,这只是一个猜测。
这就是我从子 gen_server 获取子规范的方式
child_specs() ->
[begin
Name = list_to_atom(?MODULE_STRING ++ integer_to_list(Index)),
Name, ?MODULE, start_link, [Name],
transient, 2000, worker, [bench_client]
end || Index <- lists:seq(1, 20)].
gen_server的init()函数是
init([]) ->
Config = ets:new(config, [set, named_table]),
Destinations = ets:new(destinations, [set, named_table]),
我是 erlang 的完全初学者,因此遇到了困难。
谢谢!
【问题讨论】:
【参考方案1】:私人
只有所有者进程可以读取或写入表。
你能试试ets:new(config, [set, named_table, private])
吗?
【讨论】:
no.. 试过但同样的错误。另外,出于好奇,如果那是私人的,其他孩子怎么能访问这张桌子?不过谢谢!【参考方案2】:你真的需要命名的 ets 表吗?当你命名一个表时,一个 Erlang 节点中只能存在一个同名的表。去掉 ets:new/2
调用中的 named_table
选项,您将不会再收到 badarg
异常。
【讨论】:
如果 ets 表是共享的并且存在于 erlang 虚拟机中,当第一个孩子创建 ets 表时,当第二个孩子试图创建一个新表时,为什么不抛出一个例外。谢谢! @史蒂夫 如果您没有按照我的回答使用named_table
选项,那么这两个子进程正在创建两个不同的 ets 表。例如,如果您运行erl
并连续运行两次ets:new(config, [set]).
,您可以看到这一点;两次调用返回的表 ID 将不同。
很好,帮了很多忙。谢谢!以上是关于主管创建多个孩子时的问题的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Erlang/OTP 中将主管的孩子 pid 共享给另一个孩子