有人能解释一下 Erlang 的 Pid (进程ID)结构吗?

谁能解释一下 Erlang Pid 的结构?

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

在本地节点上,A似乎总是 0,但是当 Pid 的所有者位于另一个节点上时,这个值会发生变化。

是否可以只使用 Pid 在远程节点上直接发送消息?比如: <4568.30.0> ! Message,而不必显式指定注册进程的名称和节点名称( {proc_name, Node} ! Message) ?

24612 次浏览

PID 指的是一个进程和一个节点表。因此,只有在进行调用的节点中已知消息的情况下,才能将消息直接发送到 PID。

如果您从已经运行进程的节点 知道进行调用的节点可能会起作用。

如果我没记错的话,格式是 <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

打印的进程 id < A.B.C > 由 6组成:

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

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

在爱尔朗分布中,PID 稍微大一些,因为它们包含节点原子和其他信息。(分布式 PID 格式)

当一个内部 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()]).

有关详细信息,请参阅: 内部 PID 结构, 节点创建信息 , 与 EPMD 的节点创建计数器交互

进程 id < A.B.C > 由以下部分组成:

  • 节点 id,它不是任意的,而是 dist _ entry 中该节点的内部索引。(它实际上是节点名称的原子槽整数。)
  • B,进程索引,它指代 proctab 中的内部索引,(0-> MAXPROCS)。
  • 每次到达 MAXPROCS 时序列都会增加。

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

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

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 中。更多信息在 这部分的学习你一些二郎。