Erlang 自定义取消注册\u name/2在子级终止时未被调用

Erlang 自定义取消注册\u name/2在子级终止时未被调用,erlang,otp,Erlang,Otp,我有一个simple\u one\u for\u one监管者监视一组监管者,其子规范类似于 init([]) -> {ok, {{s

我有一个
simple\u one\u for\u one
监管者监视一组监管者,其子规范类似于

init([]) ->                                                                                                                                                                                
    {ok, {{simple_one_for_one, 60, 5},                                                                                                                                                                      
          [{subsup, {subsup, start_link, []},                                                                                                                                        
            permanent, infinity, supervisor, dynamic}]}}.  
我的
start\u子项
func如下所示:

start_subsup(Name) ->
    SupName = {via, ?MODULE, Name},
    supervisor:start_child(?MODULE, [SupName]).
这里是重要的部分:我正在通过
模块注册
——我已经正确地实现了
注册名称/2
取消注册名称/1
名称/1
在哪里,以及
发送/2
(由ets表支持)。如果有必要,我也可以发布代码

我孩子的“开始链接”功能如下所示:

start_link(SupName) ->
    supervisor:start_link(SupName, ?MODULE, []).
好的,一旦一切就绪并运行,就会发生如下情况:

%% This returns a live pid. cool.    
Pid = sup:whereis_name(name),

%% I can terminate it, and it really dies
ok = supervisor:terminate_child(sup, Pid),
undefined = process_info(Pid),

%% But! it never calls unregister_name!?
Pid = sup:whereis_name(name).
我设置了所有这些,这样我就可以让子管理员死掉并重新启动,但它被名称阻止,而不是被注销


提前谢谢

您需要捕获退出信号,以便停止的子进程运行终止。在子进程的
init
中调用此函数:

process_flag(trap_exit, true)

您需要捕获退出信号,以使停止的子级运行terminate。在子进程的
init
中调用此函数:

process_flag(trap_exit, true)

这是因为您没有正确实现语义
unregister_name/2
仅在初始化时被调用以打破可能的竞争条件。否则,假定ETS模块在注册名称上设置了监视器,以便在进程终止时自动删除该名称


查看
gproc
,了解一个已经完成且比您的解决方案更加完善的解决方案。

这是因为您没有正确实现语义
unregister_name/2
仅在初始化时被调用以打破可能的竞争条件。否则,假定ETS模块在注册名称上设置了监视器,以便在进程终止时自动删除该名称


查看
gproc
,寻找一个已经完成并且比您的解决方案更加完善的解决方案。

这有点问题。通常,您不希望在进程中捕获出口。此外,在这种情况下,它不会有帮助。它在中说,如果您希望在主管尝试停止进程时调用
terminate
,则需要陷阱退出。你是说这是不好的做法吗?有两件事需要解决。只有在需要设置陷阱时,才应设置陷阱。这种情况很少发生,因为另一个进程通常可以进行清理,而不是让破碎机本身进行清理。因此,在代码库中设置许多
trap\u exit
标志通常是应用程序逻辑设计糟糕的标志。此外,这里的问题是关于注册,在这种情况下,
gen_服务器
中的终止代码路径永远不会被触及。所以旗帜绝对没有作用。好吧,我想我还不明白主管有什么事。谢谢。这有点问题。通常,您不希望在进程中捕获出口。此外,在这种情况下,它不会有帮助。它在中说,如果您希望在主管尝试停止进程时调用
terminate
,则需要陷阱退出。你是说这是不好的做法吗?有两件事需要解决。只有在需要设置陷阱时,才应设置陷阱。这种情况很少发生,因为另一个进程通常可以进行清理,而不是让破碎机本身进行清理。因此,在代码库中设置许多
trap\u exit
标志通常是应用程序逻辑设计糟糕的标志。此外,这里的问题是关于注册,在这种情况下,
gen_服务器
中的终止代码路径永远不会被触及。所以旗帜绝对没有作用。好吧,我想我还不明白主管有什么事。谢谢。是的,这解释了为什么我在otp src中找不到它。gproc看起来像是正确的锤子——谢谢!是的,这解释了为什么我在otp src中找不到它。gproc看起来像是正确的锤子——谢谢!