erlang:list_to_pid/1 with remote pid

Dániel Szoboszlay dszoboszlay@REDACTED
Sat Jun 20 21:54:15 CEST 2020


Hi,

The first number in a pid identifies the node. The local node is always 0,
remote nodes get some number assigned by the VM. This node number may
differ across VM-s. So for example you can have 3 nodes in a cluster,
a@REDACTED, b@REDACTED and c@REDACTED You spawn a process on a@REDACTED
and get back pid <0.123.456>. If you send this pid value to processes on
b@REDACTED and c@REDACTED and print it there, they may look different in
the first number. You can get something like <987.123.456> and
<654.123.456> or whatever. In this example b@REDACTED assigned the number
987 to a@REDACTED You can't tell just from looking at the pid
<987.123.456> that 987 means a@REDACTED But you can be sure that all
processes with the same first number come from the same node.

When you call binary_to_term/1 on a pid, Erlang encodes much more
information in the result than what you see in the printed form of a pid:
http://erlang.org/doc/apps/erts/erl_ext_dist.html#new_pid_ext Notably it
will include the full name of the node, not just this number we've seen so
far. So if you send this binary to a different node it will be able to
decode it properly.

I'm not 100% sure why Pid and Pid1 became different in your example. But I
suspect because of the creation value. The creation value is also in the
binary_to_term/1 output. It is meant to distinguish pids from different
runs of the node with the same name. Local pids are generated somewhat
deterministically, so for example the init process is always <0.1.0>, and
processes spawned during the boot up also usually get the same pids - or at
least identical looking pids in the shell. In fact, whenever the node boots
up, it changes its creation value, so if a node crashes and gets restarted
the new init process will have a different pid from the last one. Although
both of them will look <0.1.0> for you in the shell. But this means
list_to_pid/1 doesn't get the real creation value, it has to use some
default instead. I guess that's why <9172.91.0> =/= <9172.91.0> for you.

Cheers,
Daniel

On Sat, 20 Jun 2020 at 08:28, Yao Bao <by@REDACTED> wrote:

> Hi,
>
> By accident, I found erlang:list_to_pid/1 does not produce the same
> "thing" when putting remote pid string as the argument.
>
> And, I found this mailing list post:
> http://erlang.org/pipermail/erlang-questions/2009-February/042100.html
>
> Quite interesting, but I still can't figure out why after reading the
> whole post.
>
> I checked the source code, a function called list_to_pid_1() in
> erts/emulator/beam/bif.c handles this. Honestly speaking, I can't fully
> understand it. So I did some guess work.
>
> I wrote a simple module:
>
> %%
> %% A dist demo.
> %%
> -module(a_dist_demo).
>
> -export([start/1, loop/0]).
>
> start(Node) ->
>     spawn(Node, fun() -> loop() end).
>
> loop() ->
>     receive
>     {From, {echo, Any}} ->
>         From ! Any,
>         loop()
>     end.
>
> And two nodes get started:
>
> MacBookPro:code by$ erl -name yao1
> Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10]
> [async-threads:1] [hipe] [dtrace]
> Eshell V10.5.3  (abort with ^G)
> (yao1@REDACTED)1> Pid = a_dist_demo:start('yao2@REDACTED
> ').
> <9172.91.0>
> (yao1@REDACTED)2> Bin = erlang:term_to_binary(Pid).
> <<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,
>   107,80,114,111,46,108,111,99,97,108,0,0,0,...>>
> (yao1@REDACTED)3> io:format("~p~n", [Bin]).
>
> <<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,107,80,114,111,46,108,
>   111,99,97,108,0,0,0,91,0,0,0,0,2>>
> ok
> (yao1@REDACTED)4> Pid ! {self(), {echo, abcd}}.
> {<0.87.0>,{echo,abcd}}
> (yao1@REDACTED)5> receive X -> X end.
> abcd
> (yao1@REDACTED)6>
> (yao1@REDACTED)8> Pid1 = erlang:list_to_pid("<9172.91.0>").
> <9172.91.0>
> (yao1@REDACTED)9> Pid = Pid1.
> ** exception error: no match of right hand side value <9172.91.0>
> (yao1@REDACTED)11> Bin1 = erlang:term_to_binary(Pid1).
> <<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,
>   107,80,114,111,46,108,111,99,97,108,0,0,0,…>>
> (yao1@REDACTED)12> Bin = Bin1.
> ** exception error: no match of right hand side value
>
> <<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,
>                       107,80,114,111,46,108,111,99,97,108,0,0,0,...>>
> (yao1@REDACTED)13>
>
> MacBookPro:code by$ erl -name yao2
> Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10]
> [async-threads:1] [hipe] [dtrace]
> Eshell V10.5.3  (abort with ^G)
> (yao2@REDACTED)1> Bin =
> <<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,107,80,114,111,46,108,111,99,97,108,0,0,0,91,0,0,0,0,2>>.
> <<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,
>   107,80,114,111,46,108,111,99,97,108,0,0,0,...>>
> (yao2@REDACTED)2> Pid = erlang:binary_to_term(Bin).
> <0.91.0>
> (yao2@REDACTED)3> Pid ! {self(), {echo, 1234}}.
> {<0.87.0>,{echo,1234}}
> (yao2@REDACTED)4> receive X -> X end.
> 1234
> (yao2@REDACTED)5>
>
> The result is: the same binary produces two different shapes of pid (
> <9172.91.0> and <0.91.0> ) in two nodes. Apparently, they refer to the same
> process.
>
> I guess the remote pid need some unique information came from the remote
> node, and erlang:list_to_pid/1 just do not have those information.
>
> I hope some internal thoughts can be revealed for this.
>
> Cheers,
> Yao
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20200620/e74251cf/attachment.htm>


More information about the erlang-questions mailing list