local pid and remote pid
pid 既可以代表本地的process,也可以代表其他节点即远程 process,因此pid ! Msg,既可以向本地节点又可以向其他节点发送消息。
如何来区分local pid和remote pid呢,让我们先看看pid具体包含哪些信息。
打印pid变量的时候,其为X.Y.Z格式的数据,其中X代表的便是本地节点或者其他node(其可以为一个索引,指向某个已知节点),Y为4字节unsigned integer代表的是process id(序列号),Z为1个字节,用来标识节点的新旧(如果节点发生了crash,那么这个数值就会发生变化,通常为0)。
具体的pid数据格式请参考:http://www.erlang.org/doc/apps/erts/erl_ext_dist.html#8.8
在分布式开发中,如果节点之间交互,涉及到pid,那么erlang会自动为我们进行local pid到remote pid的转化。具体请参看下例:
为了方便我们的观察,研究,我对kernel中的rpc模块作了一点小改动,添加了一些调试信息:
rpc.erl:
handle_call/3函数 Line 99添加:
io:format(”rpc handle_call:[M:~p F:~p A:~p] From:~p~n”, [Mod, Fun, Args, To]),
handle_info/2函数 Line 148添加:
io:format(”rpc reply To: ~p Msg:~p~n”, [To, Reply]),
do_call/3函数 Line 232
io:format(”rpc docall: Node:~p self:~p~n”, [Node, self()]),
添加完这三条打印信息,随后编译rpc,将rpc.beam放置在kernerl/ebin目录下。(修改前,相信你会把rpc.erl和rpc.beam都备份一下的)。
随后我们启动两个erlang shell:
Node A: erl -sname a
Node B: erl -sname b
在Node b中,我们register一个名叫proc_on_b的process:
(b@desktop)4> register(proc_on_b, spawn(fun() -> receive Msg -> Msg end end)).
在Node [...]