来自控制台的Erlang pids

来自控制台的Erlang pids,erlang,Erlang,我看到一条信息: 与主管: -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

我看到一条信息:

与主管:

-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,以便始终可以使用具有正确pid的
ChildPid1
?需要链接到主管创建子进程的部分的方法。

我不会尝试通过Pid访问子进程,而是使用名称访问子进程,因此无论实际Pid如何,都可以访问该子进程

使用该代码,一种简单的方法是将
寄存器(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]
这是一个正确的进程,运行
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}]}]}
请注意,这并不保证
gen_server:cast/2
s始终会导致执行相应的代码,因为子进程可能刚刚被杀死,而新进程仍然没有启动(实际上已注册)


您可能希望参考卓越网站,了解有关流程注册、主管、OTP等的更多详细信息。在中还可以找到许多详细信息。

我不会尝试通过Pid访问子进程,而是使用名称访问子进程,因此无论实际Pid如何,都可以访问该子进程

使用该代码,一种简单的方法是将
寄存器(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]
这是一个正确的进程,运行
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}]}]}
请注意,这并不保证
gen_server:cast/2
s始终会导致执行相应的代码,因为子进程可能刚刚被杀死,而新进程仍然没有启动(实际上已注册)


您可能希望参考卓越网站,了解有关流程注册、主管、OTP等的更多详细信息。许多细节也可以在中找到。

当子进程pid发生变化时,这是因为进程已死亡,所以名称不会指向子进程break吗?实际上,是的,在崩溃和重新启动之间,发送给孩子的消息将丢失。我看不出这对Child1Pid的值有什么影响?谢谢,但我想更新Child1Pid,以便在控制台上传递给孩子函数?通常,简单的一对一策略用于按需启动流程。因此,应用程序生命周期内的进程数是未知的。出于这个原因,我认为在这种情况下为孩子注册不是一个好主意。根据您要执行的操作,您可以要求主管获取活动进程的列表,或者从服务器启动它们,该服务器将运行进程的列表保存在其状态变量中。当子进程pid更改时,这是因为进程已死亡,所以名称不也指向子进程中断吗?实际上,是的,在崩溃和重新启动之间,发送给孩子的消息将丢失。我看不出这对Child1Pid的值有什么影响?谢谢,但我想更新Child1Pid,以便在控制台上传递给孩子函数?通常,简单的一对一策略用于按需启动流程。因此,应用程序生命周期内的进程数是未知的。出于这个原因,我认为在这种情况下为孩子注册不是一个好主意。根据您要执行的操作,您可以要求主管获取活动进程的列表,或者从将运行进程列表保留在其状态变量中的服务器启动这些进程。