无法从 shell 生成 erlang 主管

drf*_*oob 5 erlang erlang-otp erlang-supervisor

我已经实现了一个 gen_server 和 supervisor:test_servertest_sup. 我想从 shell/CLI 测试它们。我已经编写了它们的start_link函数,以便它们的名称在本地注册。

我发现我可以test_server很好地从命令行生成,但是生成的test_sup根本不允许我与服务器进行交互。

例如,我可以test_server通过执行来生成一个:

1> spawn(test_server, start_link, []).
<0.39.0>
2> registered().
[...,test_server,...]
Run Code Online (Sandbox Code Playgroud)

我可以与服务器交互,一切看起来都很好。

但是,如果我尝试使用 做同样的事情test_sup,则在我的“CLI 过程”(使用registered/0)中不会注册新名称/Pid 。我的test_server似乎已经生成,但我无法与之交互(请参阅 Lukas Larsson 关于 SASL 的评论以了解为什么这是真的)。

我假设我在我的主管中编码了一个错误,但是这种启动主管的方法非常有效:

1> {ok, Pid}= test_sup:start_link([]).
{ok, <0.39.0>}
2> unlink(Pid).
true
3> registered().
[...,test_server,test_sup,...]
Run Code Online (Sandbox Code Playgroud)

为什么我可以生成 gen_server 但不能生成主管?


更新

我正在使用的代码可以在这篇文章中找到。我正在使用echo_serverand echo_sup,两个非常简单的模块。

鉴于该代码,这有效:

spawn(echo_server, start_link, []).
Run Code Online (Sandbox Code Playgroud)

这不会:

spawn(echo_sup, start_link, []).
Run Code Online (Sandbox Code Playgroud)

drf*_*oob 2

Bernard Duggan 在Erlang 问题邮件列表中给出了这个解释:

当链接的进程以代码“正常”退出时,链接的进程不会自动终止。这就是为什么当生成进程退出时 [echo_server] 不会退出。那么主管为什么会死呢?Supervisor 模块的内部结构实际上本身是作为 gen_server 实现的,但设置了 process_flag(trap_exit, true)。这样做的结果是,当父进程终止时,terminate() 被调用(当 trap_exit 被禁用时不会发生)并且管理程序关闭。这在监督者的上下文中是有意义的,因为监督者是由监督树中的父级产生的 - 如果它在其父级关闭时没有死亡,无论什么原因,你都会有树的悬挂“分支”。