原创作者: litaocheng   阅读:3891次   评论:0条   更新时间:2011-06-01    
pid 既可以代表本地的process,也可以代表其他节点即远程 process,因此pid ! Msg,既可以向本地节点又可以向其他节点发送消息。

如何来区分local pid和remote pid呢,让我们先看看pid具体包含哪些信息。
打印pid变量的时候,其为X.Y.Z格式的数据,其中X代表的便是本地节点或者其他node(其可以为一个索引,指向某个已知节点),Y为4字节 unsigned integer代表的是process id(序列号,max 32767),Z为4个字节,为Serial(当pid中Y到达32767时,Z则增加)。
具体的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 a中:
(a@desktop)7> rpc:call('b@desktop', erlang, whereis, [proc_on_b]).


查看屏幕的输出:
Node a:
(a@desktop)7> rpc docall: Node:'b@desktop' self:<0.35.0>
<5094.53.0>


Node b:
(b@desktop)5> rpc handle_call:[M:erlang F:whereis A:[proc_on_b]] From:{<6253.35.0>, #Ref<6253.0.0.79>}
(b@desktop)5> rpc reply To: {<6253.35.0>,#Ref<6253.0.0.79>} Msg:<0.53.0>


仔细的查看屏幕输出,在a中,显示的rpc调用process的pid为<0.35.0>,而在b中rpc module收到的From的pid为<6253.35.0>,这里erlang已经把a中的local pid转化成为b所使用的remote pid。这样,b节点可以方便的发送信息。同样a中收到的pid信息为<5094.53.0>,也是对b所返回的信息 Msg:<0.53.0>进行了转化。

是不是所有Node之间交互的pid都会进行转化呢?
我们再做下一个试验:
我们写一个模块,让其通过c:pid/3生成一个pid,然后返回给某个节点,看这个节点是否将这个pid进行了转化。
在b的某个模块(pid_test)中添加下面的函数:
get_pid() ->
c:pid(0, 2222, 1).


随后a中调用:
(a@desktop)10> rpc:call('b@desktop', pid_test, get_pid, []).
rpc docall: Node:'b@desktop' self:<0.35.0>

<5094.2222.1>

同样,b中的pid:<0.2222.1> 贝进行了转化。

对于global module,如果我们中间传递了local pid,在另一方显示的是remote pid。
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics