题
有人能解释一下 Erlang 中 Pid 的结构吗?
Pids 看起来像这样: <A.B.C>
,例如<0.30.0> ,但我想知道这三个“位”的含义是什么:A、B 和 C。
“A”在本地节点上似乎始终为 0,但是当 Pid 的所有者位于另一个节点上时,该值会发生变化。
是否可以仅使用 Pid 直接在远程节点上发送消息?像这样的东西:<4568.30.0>!Message ,无需显式指定注册进程的名称和节点名称( {proc_name, Node} !信息 ) ?
解决方案
打印的进程 id <A.B.C> 由以下组成 6:
在内部,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 交互
其他提示
如果我没记错,格式为<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>由以下部分组成:
- A,节点 ID,它不是任意的,而是该节点在 dist_entry 中的内部索引。(它实际上是节点名称的原子槽整数。)
- B、进程索引,指的是proctab中的内部索引,(0 -> MAXPROCS)。
- C,串行,每次达到 MAXPROCS 时都会增加。
2 位的创建标记不会显示在 pid 中,而是在内部使用,并在每次节点重新启动时增加。
PID指的是进程和节点表。因此,如果在您进行呼叫的节点中已知消息,则只能将消息直接发送到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中。有关详细信息,请参阅本节了解一些Erlang。