Can someone explain the structure of a Pid (Process Identifier) in Erlang?

23,768

Solution 1

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

Solution 2

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

Solution 3

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.

Solution 4

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.

Share:
23,768
jideel
Author by

jideel

Updated on July 05, 2022

Comments

  • jideel
    jideel almost 2 years

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

  • Shruti Singh
    Shruti Singh over 15 years
    Did you have seen this big red warning? list_to_pid/1 And also you can simply send {proc_name, Node} ! message or use module global if you want use global names.
  • mrjohnsly
    mrjohnsly almost 15 years
    You can only register local pids - to register remote pids you'd need to use the global registration module (or roll your own registration system).
  • mcandre
    mcandre over 13 years
    pid_to_list/1 takes a pid and returns its string representation.
  • btk
    btk over 9 years
    Thanks for mentioning list_to_pid - just what I was looking for. Here's a bit more info on it (specifically, that you cannot use it with external pids: stackoverflow.com/questions/10475321/…)
  • opyate
    opyate almost 8 years
    FYI, this matches: Pid = pid(0,123,0), Pid = list_to_pid("<0.123.0>"). (tested on 18)