有人能解释一下Erlang中Pid的结构吗?

时间:2008-10-28 13:42:21

标签: erlang pid

有人可以解释Erlang中Pid的结构吗?

Pids看起来像这样: <A.B.C> ,例如&LT; 0.30.0&GT; ,但我想知道这三个“位”的含义是什么:A,B和C.

本地节点上的'A'似乎始终为0,但当Pid的所有者位于另一个节点上时,此值会发生变化。

是否可以仅使用Pid在远程节点上直接发送消息?类似的东西:&lt; 4568.30.0&gt; !消息,无需明确指定已注册进程的名称和节点名称({proc_name,Node}!Message)?

5 个答案:

答案 0 :(得分:69)

印刷工艺ID&lt; A.B.C&gt;由6组成:

  • A,节点编号(0是本地编号 节点,远程节点的任意数字)
  • B,进程号的前15位(进程表的索引)7
  • C,进程号的16-18位(与B相同的进程号)7

在内部,32位仿真器上的进程号为28位宽。 B和C的奇怪定义来自R9B和早期版本的Erlang,其中B是15位进程ID,C是在达到最大进程ID并且重用较低ID时递增的换行计数器。

在erlang发行版中,PID稍大一些,因为它们包含节点原子以及其他信息。 (Distributed PID format

当内部PID从一个节点发送到另一个节点时,它会自动转换为外部/分布式PID表单,因此一个节点上可能<0.10.0>inet_db)的结果可能最终为发送到另一个节点时<2265.10.0>。您可以正常发送到这些PID。

% get the PID of the user server on OtherNode
RemoteUser = rpc:call(OtherNode, erlang,whereis,[user]), 

true = is_pid(RemoteUser),

% send message to remote PID
RemoteUser ! ignore_this, 

% print "Hello from <nodename>\n" on the remote node's console.
io:format(RemoteUser, "Hello from ~p~n", [node()]). 

有关详细信息,请参阅:Internal PID structureNode creation informationNode creation counter interaction with EPMD

答案 1 :(得分:13)

如果我没记错,格式为<nodeid,serial,creation>。 0是当前节点,很像计算机总是有主机名“localhost”来引用它自己。这是旧的记忆,所以它可能不是100%正确的坚韧。

但是是的。例如,您可以使用list_to_pid/1构建pid。

PidString = "<0.39.0>",
list_to_pid(PidString) ! message.

当然。您只需使用您需要的任何方法来构建PidString。可能会编写一个生成它的函数,并使用它来代替PidString,如下所示:

list_to_pid( make_pid_from_term({proc_name, Node}) ) ! message

答案 2 :(得分:8)

进程ID&lt; A.B.C&gt;由...组成:

  • A,节点id不是任意的,而是dist_entry中该节点的内部索引。 (它实际上是节点名称的原子槽整数。)
  • B,流程索引,指的是proctab中的内部索引,(0 - &gt; MAXPROCS)。
  • C,Serial,每次达到MAXPROCS都会增加。

2位的创建标记不会显示在pid中,而是在内部使用,并在每次重新启动时增加。

答案 3 :(得分:2)

PID指的是进程和节点表。因此,如果在您进行呼叫的节点中已知消息,则只能将消息直接发送到PID。

如果您从运行该进程的节点已经knows about进行调用的节点,这可能会起作用。

答案 4 :(得分:0)

除了别人所说的,你可能会发现这个简单的实验有助于理解内部发生的事情:

1> node().
nonode@nohost
2> term_to_binary(node()).
<<131,100,0,13,110,111,110,111,100,101,64,110,111,104,111,
  115,116>>
3> self().                
<0.32.0>
4> term_to_binary(self()).
<<131,103,100,0,13,110,111,110,111,100,101,64,110,111,104,
  111,115,116,0,0,0,32,0,0,0,0,0>>

因此,您可以将节点名称内部存储在pid中。更多信息,请参阅this section了解你一些Erlang。