我看到了消息:
https://stackoverflow.com/a/4837832/1236509
与主管:
-module(root_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
start_link() ->
{ok, Pid} = supervisor:start_link({local, ?MODULE},
?MODULE, []),
erlang:unlink(Pid),
{ok, Pid}.
init(_Args) ->
RestartStrategy = {simple_one_for_one, 10, 60},
ChildSpec = {ch1, {ch1, start_link, []},
permanent, brutal_kill, worker, [ch1]},
Children = [ChildSpec],
{ok, {RestartStrategy, Children}}.
在控制台人员电话中:
{ok, ChildPid1} = root_sup:start_link().
当子pid更改ChildPid1
获取新pid的方式时,总是可以使用ChildPid1
正确的pid?需要链接到创建孩子的主管的一部分。
答案 0 :(得分:1)
我不会尝试通过Pid访问孩子,而是register/2名称下的子进程,因此无论实际的Pid如何都可以访问。
使用代码from the answer you reference,一种简单的方法是将register(ch1, self()),
添加到子进程的init进程中。这会给ch1.erl
:
init(_Args) ->
io:format("ch1 has started (~w)~n", [self()]),
% register a name to this process
register(child, self()),
{ok, ch1State}.
这会将子self()
的pid注册到名称child
我们可以看到它有效:
1> root_sup:start_link().
{ok,<0.34.0>}
2> supervisor:start_child(root_sup, []).
ch1 has started (<0.36.0>)
{ok,<0.36.0>}
3> lists:filter(fun(X) -> X == child end, registered()).
[child]
我们确实有一个名为child
。
4> gen_server:cast(child, calc).
result 2+2=4
这是运行ch1.erl
代码的正确过程。
让我们通过调用错误的代码来破坏这个过程:
5> gen_server:cast(child, calcbad).
result 1/0
ok
ch1 has started (<0.41.0>)
6>
=ERROR REPORT==== 28-Oct-2012::01:31:30 ===
** Generic server <0.36.0> terminating
** Last message in was {'$gen_cast',calcbad}
** When Server state == ch1State
** Reason for termination ==
** {'function not exported',
[{ch1,terminate,
[{badarith,
[{ch1,handle_cast,2,[{file,"ch1.erl"},{line,27}]},
{gen_server,handle_msg,5,
[{file,"gen_server.erl"},{line,607}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,227}]}]},
ch1State],
[]},
{gen_server,terminate,6,[{file,"gen_server.erl"},{line,722}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,227}]}]}
因此,孩子,流程<0.36.0>
崩溃了,一个新的孩子<0.41.0>
开始承担死者<0.36.0>
的职责。由于此新流程以相同名称注册,calc
将再次起作用:
6> gen_server:cast(child, calc).
result 2+2=4
ok
请注意,这并不能保证gen_server:cast/2
总是会导致执行相应的代码,因为孩子可能刚刚被杀死,而新进程仍未启动(事实上已注册)。 / p>
有关流程注册,主管,OTP等的更多详细信息,您可能需要参考优秀的Programming Erlang: Software for a Concurrent World by Joe Armstrong。许多细节也可以在the online documentation of OTP中找到。