有人可以用Erlang解释Pid的结构吗?
点看起来像这样:<A.B.C>
,例如<0.30.0>,但是我想知道这三个“位”(A,B和C)的含义是什么。
“ A”在本地节点上似乎始终为0,但是当Pid的所有者位于另一个节点上时,此值会更改。
是否可以仅使用Pid在远程节点上直接发送消息?像这样:<4568.30.0>!消息,而不必显式指定已注册进程的名称和节点名称({proc_name,Node}!消息)?
Answers:
打印的进程ID <ABC>由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%正确的解决方案。
但是,是的。例如,您可以使用构建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
Pid = pid(0,123,0), Pid = list_to_pid("<0.123.0>").
在18日测试)
除了其他人说的话,您可能会发现这个简单的实验对于了解内部发生的事情很有用:
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”中的更多信息。