Erlang/OTP's global 模块可用于以原子的形式为Erlang分布式系统中的进程命名,确保同一时刻分布式系统中的每个进程都有唯一的一个名字。
现在来看看global模块在实际操作中的表现吧,我们在两个一开始并未连接的Erlang结点中注册同一个名字,然后再将这两个结点连接起来,这时,系统将监测到两个节点中有相同的名字,将注销一个节点中的名字注册。
首先,在两个独立的节点上分别注册名字a(这两个节点分别以erl -sname one and erl -sname two启动), 在one节点进行以下操作,
Eshell V5.6.2 (abort with ^G)
(one@cuiweican)1> global:register_name(a, self()).
yes
(one@cuiweican)2> global:whereis_name(a).
<0.37.0>
从以上可以看到名字注册成功了(register_name返回值为yes),当使用whereis_name进行查询时,正如我们所期望,该函数返回了self()的值,即进程Shell的Pid。
现在two结点上进行相同的操作。
Eshell V5.6.2 (abort with ^G)
(two@cuiweican)1> global:register_name(a, self()).
yes
(two@cuiweican)2> global:whereis_name(a).
<0.37.0>
同样,名字注册成功了。注意到这两个节点都成功注册了全局名字 a,这是因为这两个节点之间并未有连接。一旦这两节点连接,Erlang/OTP 将自动解决这种冲突,默认情况下,将会注销其中的一个名字注册。
现在来看看当两个节点连接时,会发生什么吧。我们通过从节点one向节点two ping使两个节点为连接起来。
(one@cuiweican)3> net_adm:ping(two@cuiweican).
pong
(one@cuiweican)4>
=INFO REPORT==== 13-Feb-2009::03:05:22 ===
global: Name conflict terminating {a,<5744.37.0>}
(one@cuiweican)4> global:whereis_name(a).
<0.37.0>
(one@cuiweican)5>
从其中一个节点输出的报告信息来看,其中节点two的名字被注销了。在节点two进行查询名字a时,会发现名字a在节点one中注册。