2

文档

请注意,当重启策略为 simple_one_for_one 时,子规范列表必须是只有一个子规范的列表。(忽略子规范标识符。)然后在初始化阶段不启动子进程,但假定所有子进程都使用 supervisor:start_child/2 动态启动。

零件的设计考虑是什么?它不会停止主动调用register(<chid_id>, ChildPid) 每个子进程。

4

1 回答 1

3

为子进程的PID注册名称与主管无关。

考虑一个沼泽标准监督者(不是动态的),子规范为监督者提供了足够的信息来启动子进程,通常通过调用 child_module:start_link,但它是 child_module:start_link 的实现,它确定了进程的启动方式和可能的名称登记。典型的 child_module:start_link 实现类似于:

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

正是这个对 gen_server:start_link/4 的调用导致注册生成的 gen_server 进程 PID 的名称为“server_name”。

您可以改为调用 gen_server:start_link/3 ,在这种情况下, gen_server 进程将没有名称,除非您在 init/1 行为实现中调用 erlang:register/2 或类似的东西。

这很好,因为没有理由将名称注册与监督结合起来,模块/进程的名称与该模块及其服务有关,它是如何访问和使用的,而不是与监督策略有关。

受监督进程为自己注册名称是很常见的,因此成为任何其他进程都可以轻松访问的命名服务。

然而,对于简单的一对一监督,通常被监督的孩子不会有名字,因为他们应该是同质的(即不要创建一个简单的一对一监督者来动态启动各种工作人员,他们都做不同的事情,如果他们做不同的事情,那么它们几乎可以肯定具有不同的相对重要性,它们应该在不同的主管之下),因此,唯一的名称是没有用的/不合适的。

那么在调用 start_child 时您不能选择不同的子标识符的原因是,子标识符实际上是子规范的 ID(即子的类型),而不是子进程的 ID。使用不同的子标识符会说“这是一种不同类型的进程,它做的事情与另一个不同”。这符合子规范是一个列表的要求。

于 2016-01-22T12:08:58.767 回答