我有两个erlang节点,node01是'vm01@192.168.146.128'
,node02是'vm02@192.168.146.128'
。我想在node02上使用spawn(Node, Mod, Fun, Args)
在node01上启动一个进程,但我总是得到无用的pid。
节点连接正常:
(vm02@192.168.146.128)14> net_adm:ping('vm01@192.168.146.128').
pong
模块位于node01和node02:
的路径中(vm01@192.168.146.128)7> m(remote_process).
Module: remote_process
MD5: 99784aa56b4feb2f5feed49314940e50
Compiled: No compile time info available
Object file: /src/remote_process.beam
Compiler options: []
Exports:
init/1
module_info/0
module_info/1
start/0
ok
(vm02@192.168.146.128)20> m(remote_process).
Module: remote_process
MD5: 99784aa56b4feb2f5feed49314940e50
Compiled: No compile time info available
Object file: /src/remote_process.beam
Compiler options: []
Exports:
init/1
module_info/0
module_info/1
start/0
ok
然而,产卵不成功:
(vm02@192.168.146.128)21> spawn('vm01@192.168.146.128', remote_process, start, []).
I'm on node 'vm01@192.168.146.128'
<9981.89.0>
My pid is <9981.90.0>
(vm01@192.168.146.128)8> whereis(remote_process).
undefined
该过程能够在本地节点上运行:
(vm02@192.168.146.128)18> remote_process:start().
I'm on node 'vm02@192.168.146.128'
My pid is <0.108.0>
{ok,<0.108.0>}
(vm02@192.168.146.128)24> whereis(remote_process).
<0.115.0>
但它在远程节点上失败了。谁能给我一些想法?
这是源代码remote_process.erl:
-module(remote_process).
-behaviour(supervisor).
-export([start/0, init/1]).
start() ->
{ok, Pid} = supervisor:start_link({global, ?MODULE}, ?MODULE, []),
{ok, Pid}.
init([]) ->
io:format("I'm on node ~p~n", [node()]),
io:format("My pid is ~p~n", [self()]),
{ok, {{one_for_one, 1, 5}, []}}.
答案 0 :(得分:2)
您正在为您的流程使用全局注册,这是您的目的所必需的。检索它的函数是global:whereis_name(remote_process)
。
编辑:如果
,则有效如果不满足任何这些条件,您将获得undefined
编辑2:使用:werl -sname p1
启动节点1并输入shell:
(p1@W7FRR00423L)1> c(remote_process).
{ok,remote_process}
(p1@W7FRR00423L)2> remote_process:start().
I'm on node p1@W7FRR00423L
My pid is <0.69.0>
{ok,<0.69.0>}
(p1@W7FRR00423L)3> global:whereis_name(remote_process).
<0.69.0>
(p1@W7FRR00423L)4>
然后用werl - sname p2
启动第二个节点并输入shell(稍后可以连接第二个节点,全局注册是&#34;更新&#34;必要时):
(p2@W7FRR00423L)1> net_kernel:connect_node(p1@W7FRR00423L).
true
(p2@W7FRR00423L)2> nodes().
[p1@W7FRR00423L]
(p2@W7FRR00423L)3> global:whereis_name(remote_process).
<7080.69.0>
(p2@W7FRR00423L)4>
(p2@W7FRR00423L)4>
编辑3:
在测试中,您将在远程节点上生成一个进程P1
,该进程执行函数remote_process:start/0
。
此函数调用supervisor:start_link/3
,它基本上产生一个新的管理程序进程P2
并将其自身链接到它。在此之后,P1
无所事事,因此它会死亡,导致关联的流程P2
也会死亡,并且您会收到undefined
来回global:whereis_name
的回复。
在我的测试中,我从远程节点的shell启动进程;在评估remote_process:start/0
之后,shell不会消失,因此主管进程不会死亡,global:whereis_name
会找到请求的pid。
如果您希望主管在通话中生存,您需要一个不带链接的中间过程,因此它不会因其父级而死亡。我根据你的代码给你一个小例子:
-module(remote_process).
-behaviour(supervisor).
-export([start/0, init/1,local_spawn/0,remote_start/1]).
remote_start(Node) ->
spawn(Node,?MODULE,local_spawn,[]).
local_spawn() ->
% spawn without link so start_wait_stop will survive to
% the death of local_spawn process
spawn(fun start_wait_stop/0).
start_wait_stop() ->
start(),
receive
stop -> ok
end.
start() ->
io:format("start (~p)~n",[self()]),
{ok, Pid} = supervisor:start_link({global, ?MODULE}, ?MODULE, []),
{ok, Pid}.
init([]) ->
io:format("I'm on node ~p~n", [node()]),
io:format("My pid is ~p~n", [self()]),
{ok, {{one_for_one, 1, 5}, []}}.
在节点1中的shell中
(p1@W7FRR00423L)1> net_kernel:connect_node(p2@W7FRR00423L).
true
(p1@W7FRR00423L)2> c(remote_process).
{ok,remote_process}
(p1@W7FRR00423L)3> global:whereis_name(remote_process).
undefined
(p1@W7FRR00423L)4> remote_process:remote_start(p2@W7FRR00423L).
<7080.68.0>
start (<7080.69.0>)
I'm on node p2@W7FRR00423L
My pid is <7080.70.0>
(p1@W7FRR00423L)5> global:whereis_name(remote_process).
<7080.70.0>
(p1@W7FRR00423L)6> global:whereis_name(remote_process).
undefined
和节点2
(p2@W7FRR00423L)1> global:registered_names(). % before step 4
[]
(p2@W7FRR00423L)2> global:registered_names(). % after step 4
[remote_process]
(p2@W7FRR00423L)3> rp(processes()).
[<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>,
<0.34.0>,<0.35.0>,<0.36.0>,<0.37.0>,<0.38.0>,<0.39.0>,
<0.40.0>,<0.41.0>,<0.42.0>,<0.43.0>,<0.44.0>,<0.45.0>,
<0.46.0>,<0.47.0>,<0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,
<0.52.0>,<0.53.0>,<0.54.0>,<0.55.0>,<0.56.0>,<0.57.0>,
<0.58.0>,<0.62.0>,<0.64.0>,<0.69.0>,<0.70.0>]
ok
(p2@W7FRR00423L)4> pid(0,69,0) ! stop. % between steps 5 and 6
stop
(p2@W7FRR00423L)5> global:registered_names().
[]