74

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

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

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

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

4

5 回答 5

83

打印的进程 ID <ABC> 由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 稍大一些,因为它们包括节点原子以及其他信息。(分布式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 的交互

于 2008-11-04T15:29:26.680 回答
13

如果我没记错的话,格式是<nodeid,serial,creation>. 0 是当前节点,就像计算机始终使用主机名“localhost”来引用自身一样。这是旧记忆,所以它可能不是 100% 正确的。

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

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

当然。您只需使用您需要使用的任何方法来构建您的 PidString。可能编写一个生成它的函数并使用它而不是像这样的 PidString:

list_to_pid( make_pid_from_term({proc_name, Node}) ) ! message
于 2008-10-28T15:09:17.977 回答
8

进程id<ABC>组成:

  • A,节点 id 不是任意的,而是 dist_entry 中该节点的内部索引。(它实际上是节点名称的原子槽整数。)
  • B、进程索引,即proctab中的内部索引,(0 -> MAXPROCS)。
  • C,每次达到 MAXPROCS 时增加的序列号。

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

于 2009-04-30T23:17:12.320 回答
3

PID 指的是一个进程和一个节点表。因此,您只能将消息直接发送到 PID,前提是它在您进行调用的节点中是已知的。

如果您从中进行调用的节点已经知道进程正在运行的节点,那么这可能会起作用。

于 2008-10-28T14:24:20.830 回答
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 中。更多信息参阅Learn You Some Erlang。

于 2015-02-16T13:14:14.157 回答