有人可以解释一下 Erlang 中 Pid(进程标识符)的结构吗?

发布于 2024-07-07 20:11:35 字数 407 浏览 6 评论 0原文

有人能解释一下 Erlang 中 Pid 的结构吗?

Pids 看起来像这样: ,例如 <0.30.0> ,但我想知道这三个“位”的含义是什么:<代码>A、BC

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

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

Can someone explain the structure of a Pid in Erlang?

Pids looks like this: <A.B.C>, e.g. <0.30.0> , but I would like to know what is the meaning of these three "bits": A, B and C.

A seems to be always 0 on a local node, but this value changes when the Pid's owner is located on another node.

Is it possible to directly send a message on a remote node using only the Pid? Something like that: <4568.30.0> ! Message, without having to explicitly specify the name of the registered process and the node name ({proc_name, Node} ! Message)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

断舍离 2024-07-14 20:11:35

打印的进程 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 结构< /a>,
节点创建信息,
节点创建计数器与 EPMD 交互

Printed process ids < A.B.C > are composed of 6:

  • A, the node number (0 is the local
    node, an arbitrary number for a remote node)
  • B, the first 15 bits of the process number (an index into the process table) 7
  • C, bits 16-18 of the process number (the same process number as B) 7

Internally, the process number is 28 bits wide on the 32 bit emulator. The odd definition of B and C comes from R9B and earlier versions of Erlang in which B was a 15bit process ID and C was a wrap counter incremented when the max process ID was reached and lower IDs were reused.

In the erlang distribution PIDs are a little larger as they include the node atom as well as the other information. (Distributed PID format)

When an internal PID is sent from one node to the other, it's automatically converted to the external/distributed PID form, so what might be <0.10.0> (inet_db) on one node might end up as <2265.10.0> when sent to another node. You can just send to these PIDs as normal.

% 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()]). 

For more information see: Internal PID structure,
Node creation information,
Node creation counter interaction with EPMD

┼── 2024-07-14 20:11:35

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

If I remember this correctly the format is <nodeid,serial,creation>.
0 is current node much like a computer always has the hostname "localhost" to refer to itself. This is by old memory so it might not be 100% correct tough.

But yes. You could build the pid with list_to_pid/1 for example.

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

Of course. You just use whatever method you need to use to build your PidString. Probably write a function that generates it and use that instead of PidString like such:

list_to_pid( make_pid_from_term({proc_name, Node}) ) ! message
听不够的曲调 2024-07-14 20:11:35

进程号< ABC> 由以下部分组成:

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

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

Process id < A.B.C > is composed of:

  • A, node id which is not arbitrary but the internal index for that node in dist_entry. (It is actually the atom slot integer for the node name.)
  • B, process index which refers to the internal index in the proctab, (0 -> MAXPROCS).
  • C, Serial which increases every time MAXPROCS has been reached.

The creation tag of 2 bits is not displayed in the pid but is used internally and increases every time the node restarts.

套路撩心 2024-07-14 20:11:35

PID指的是进程和节点表。 因此,只有在您进行调用的节点中已知 PID 时,您才能直接向 PID 发送消息。

如果您进行调用的节点已经 了解 进程正在运行的节点。

The PID refers to a process and a node table. So you can only send a message directly to a PID if it is known in the node from which you do the call.

It is possible that this will work if the node you do the call from already knows about the node on which the process is running.

情愿 2024-07-14 20:11:35

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

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”的本节

Apart from what others have said, you may find this simple experiment useful to understand what is going on internally:

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>>

So, you can se that the node name is internally stored in the pid. More info in this section of Learn You Some Erlang.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文