原创作者: 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添加:
handle_info/2函数 Line 148添加:
do_call/3函数 Line 232
添加完这三条打印信息,随后编译rpc,将rpc.beam放置在kernerl/ebin目录下。(修改前,相信你会把rpc.erl和rpc.beam都备份一下的)。
随后我们启动两个erlang shell:
在Node b中,我们register一个名叫proc_on_b的process:
在Node a中:
查看屏幕的输出:
Node a:
Node b:
仔细的查看屏幕输出,在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)中添加下面的函数:
随后a中调用:
<5094.2222.1>
同样,b中的pid:<0.2222.1> 贝进行了转化。
对于global module,如果我们中间传递了local pid,在另一方显示的是remote pid。
如何来区分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 条 请登录后发表评论