1

我有一个simple_one_for_one主管在监视一组主管,其子规格类似于

init([]) ->                                                                                                                                                                                
    {ok, {{simple_one_for_one, 60, 5},                                                                                                                                                                      
          [{subsup, {subsup, start_link, []},                                                                                                                                        
            permanent, infinity, supervisor, dynamic}]}}.  

我的start_child函数如下所示:

start_subsup(Name) ->
    SupName = {via, ?MODULE, Name},
    supervisor:start_child(?MODULE, [SupName]).

via这是重要的部分:我正在注册?MODULE- 我已正确实施register_name/2, unregister_name/1, whereis_name/1, 和send/2(由 ets 表支持)。如有必要,我也可以发布该代码。

我孩子的 start_link 函数如下所示:

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).

我设置了所有这些,以便我可以让子主管死亡并重新启动,但它被未注册的名称所阻止。

提前致谢!

4

2 回答 2

1

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

寻找gproc一个已经完成并且比你的更完善的解决方案。

于 2013-07-11T22:45:22.370 回答
0

You need to trap exit signals for a stopped child to run terminate. Call this in your child process's init:

process_flag(trap_exit, true)
于 2013-07-11T00:30:57.417 回答