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看起来像是正确的锤子——谢谢!