有人可以解释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)?
答案 0 :(得分:69)
印刷工艺ID&lt; A.B.C&gt;由6组成:
在内部,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 structure, Node creation information, Node 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;由...组成:
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。