<html><head><meta http-equiv="Content-Type" content="text/html charset=gb2312"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hello,</div><div class=""><br class=""></div><div class="">Thanks for the detailed explanation about it.</div><div class=""><br class=""></div><div class="">Based on the documentation you mentioned, I write a function to parse the PidBin, and here it is:</div><div class=""><br class=""></div><div class="">%% Begin</div><div class=""><br class=""></div><div class=""><span class="">parse_bin_pid(BinPid) -><br class=""> XLen = 1,<br class=""> FlagLen = 1,<br class=""> IDLen = 4,<br class=""> SerialLen = 4,<br class=""> CreationLen = 1,<br class=""> NodeLen = erlang:byte_size(BinPid) - (XLen + FlagLen + IDLen + SerialLen + CreationLen),<br class=""> <<<br class=""> X:XLen/binary, % What is this?<br class=""> Flag:FlagLen/binary,<br class=""> Node:NodeLen/binary,<br class=""> ID:IDLen/binary,<br class=""> Serial:SerialLen/binary,<br class=""> Creation:CreationLen/binary<br class=""> >> = BinPid,<br class=""> {X, Flag, Node, ID, Serial, Creation}.<br class=""><br class="">test_parse_bin_pid() -><br class=""> Pid = erlang:self(),<br class=""> Bin = erlang:term_to_binary(Pid),<br class=""> parse_bin_pid(Bin).<br class=""></span></div><div class=""><span class=""><br class=""></span></div><div class="">%% End</div><div class=""><br class=""></div><div class="">And, I test it with two local nodes to find the differences:</div><div class=""><br class=""></div><div class=""># 1</div><div class=""><div class="">MacBookPro:code by$ erl -sname yao1</div><div class="">Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]</div><div class=""><br class=""></div><div class="">Eshell V10.5.3 (abort with ^G)</div><div class="">(yao1@MacBookPro)1> my_lib_misc:test_parse_bin_pid().</div><div class="">{<<131>>,</div><div class=""> <<"g">>,</div><div class=""> <<100,0,15,121,97,111,49,64,77,97,99,66,111,111,107,80,</div><div class=""> 114,111>>,</div><div class=""> <<0,0,0,87>>,</div><div class=""> <<0,0,0,0>>,</div><div class=""> <<3>>}</div><div class="">(yao1@MacBookPro)2> erlang:self().</div><div class=""><0.87.0></div><div class="">(yao1@MacBookPro)3> </div></div><div class=""><br class=""></div><div class=""># 2</div><div class=""><div class="">MacBookPro:code by$ erl -sname yao2</div><div class="">Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]</div><div class=""><br class=""></div><div class="">Eshell V10.5.3 (abort with ^G)</div><div class="">(yao2@MacBookPro)1> my_lib_misc:test_parse_bin_pid().</div><div class="">{<<131>>,</div><div class=""> <<"g">>,</div><div class=""> <<100,0,15,121,97,111,50,64,77,97,99,66,111,111,107,80,</div><div class=""> 114,111>>,</div><div class=""> <<0,0,0,87>>,</div><div class=""> <<0,0,0,0>>,</div><div class=""> <<1>>}</div><div class="">(yao2@MacBookPro)2> erlang:self().</div><div class=""><0.87.0></div><div class="">(yao2@MacBookPro)3> </div></div><div class=""><br class=""></div><div class="">In my environment, PID_EXT is used, both Node and Creation are different in two local nodes.</div><div class=""><br class=""></div><div class="">Back to the module a_dist_demo:</div><div class=""><br class=""></div><div class=""><div class="">Eshell V10.5.3 (abort with ^G)</div><div class="">(<a href="mailto:yao1@MacBookPro.local" class="">yao1@MacBookPro.local</a>)1> Pid = a_dist_demo:start('<a href="mailto:yao2@MacBookPro.local" class="">yao2@MacBookPro.local</a>').</div><div class=""><9222.131.0></div><div class="">(<a href="mailto:yao1@MacBookPro.local" class="">yao1@MacBookPro.local</a>)2> Pid1 = erlang:list_to_pid("<9222.131.0>").</div><div class=""><9222.131.0></div><div class="">(<a href="mailto:yao1@MacBookPro.local" class="">yao1@MacBookPro.local</a>)3> my_lib_misc:parse_bin_pid(erlang:term_to_binary(Pid)). </div><div class="">{<<131>>,</div><div class=""> <<"g">>,</div><div class=""> <<100,0,21,121,97,111,50,64,77,97,99,66,111,111,107,80,</div><div class=""> 114,111,46,108,111,99,97,108>>,</div><div class=""> <<0,0,0,131>>,</div><div class=""> <<0,0,0,0>>,</div><div class=""> <<1>>}</div><div class="">(<a href="mailto:yao1@MacBookPro.local" class="">yao1@MacBookPro.local</a>)4> my_lib_misc:parse_bin_pid(erlang:term_to_binary(Pid1)).</div><div class="">{<<131>>,</div><div class=""> <<"g">>,</div><div class=""> <<100,0,21,121,97,111,50,64,77,97,99,66,111,111,107,80,</div><div class=""> 114,111,46,108,111,99,97,108>>,</div><div class=""> <<0,0,0,131>>,</div><div class=""> <<0,0,0,0>>,</div><div class=""> <<0>>}</div></div><div class=""><div class="">(<a href="mailto:yao1@MacBookPro.local" class="">yao1@MacBookPro.local</a>)7> Bin = erlang:term_to_binary(Pid). </div><div class=""><<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,</div><div class=""> 107,80,114,111,46,108,111,99,97,108,0,0,0,...>></div><div class="">(<a href="mailto:yao1@MacBookPro.local" class="">yao1@MacBookPro.local</a>)8> Bin1 = erlang:term_to_binary(Pid1).</div><div class=""><<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,</div><div class=""> 107,80,114,111,46,108,111,99,97,108,0,0,0,…>></div></div><div class=""><div class="">(<a href="mailto:yao1@MacBookPro.local" class="">yao1@MacBookPro.local</a>)9> {X, Y} = erlang:split_binary(Bin, erlang:byte_size(Bin)-1).</div><div class="">{<<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,</div><div class=""> 107,80,114,111,46,108,111,99,97,108,0,0,...>>,</div><div class=""> <<1>>}</div></div><div class=""><div class="">(<a href="mailto:yao1@MacBookPro.local" class="">yao1@MacBookPro.local</a>)12> Bin1 = <<X/binary, <<0>>/binary>>.</div><div class=""><<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,</div><div class=""> 107,80,114,111,46,108,111,99,97,108,0,0,0,…>></div></div><div class=""><br class=""></div><div class="">As you mentioned, the difference comes from the creation value, the erlang:list_to_pid/1 always set the creation value to 0, and this is why Pid =/= Pid1.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Yao</div><br class=""><div><blockquote type="cite" class=""><div class="">在 2020年6月21日,03:54,Dániel Szoboszlay <<a href="mailto:dszoboszlay@gmail.com" class="">dszoboszlay@gmail.com</a>> 写道:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi,<div class=""><br class=""></div><div class="">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@localhost, b@localhost and c@localhost. You spawn a process on a@localhost and get back pid <0.123.456>. If you send this pid value to processes on b@localhost and c@localhost 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@localhost assigned the number 987 to a@localhost. You can't tell just from looking at the pid <987.123.456> that 987 means a@localhost. But you can be sure that all processes with the same first number come from the same node.</div><div class=""><br class=""></div><div class="">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: <a href="http://erlang.org/doc/apps/erts/erl_ext_dist.html#new_pid_ext" class="">http://erlang.org/doc/apps/erts/erl_ext_dist.html#new_pid_ext</a> 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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Daniel</div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, 20 Jun 2020 at 08:28, Yao Bao <<a href="mailto:by@meetlost.com" class="">by@meetlost.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;" class="">Hi,<br class=""><br class="">By accident, I found erlang:list_to_pid/1 does not produce the same "thing" when putting remote pid string as the argument.<br class=""><br class="">And, I found this mailing list post: <a href="http://erlang.org/pipermail/erlang-questions/2009-February/042100.html" target="_blank" class="">http://erlang.org/pipermail/erlang-questions/2009-February/042100.html</a><div class=""><br class=""><div class="">Quite interesting, but I still can't figure out why after reading the whole post.<br class=""><br class="">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.<br class=""><br class="">I wrote a simple module:<div class=""><br class="">%%<br class="">%% A dist demo.<br class="">%%<br class="">-module(a_dist_demo).<br class=""><br class="">-export([start/1, loop/0]).<br class=""><br class="">start(Node) -><br class=""> spawn(Node, fun() -> loop() end).<br class=""><br class="">loop() -><br class=""> receive<br class=""> {From, {echo, Any}} -><br class=""> From ! Any,<br class=""> loop()<br class=""> end.<br class=""><br class=""><div class="">And two nodes get started:</div><div class=""><br class=""></div></div><div class=""><div class="">MacBookPro:code by$ erl -name yao1</div><div class="">Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]</div><div class="">Eshell V10.5.3 (abort with ^G)</div><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)1> Pid = a_dist_demo:start('<a href="mailto:yao2@MacBookPro.local" target="_blank" class="">yao2@MacBookPro.local</a>').</div><div class=""><9172.91.0></div><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)2> Bin = erlang:term_to_binary(Pid).</div><div class=""><<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,</div><div class=""> 107,80,114,111,46,108,111,99,97,108,0,0,0,...>></div><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)3> io:format("~p~n", [Bin]).</div><div class=""><<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,107,80,114,111,46,108,</div><div class=""> 111,99,97,108,0,0,0,91,0,0,0,0,2>></div><div class="">ok</div><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)4> Pid ! {self(), {echo, abcd}}.</div><div class="">{<0.87.0>,{echo,abcd}}</div><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)5> receive X -> X end.</div><div class="">abcd</div></div><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)6></div><div class=""><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)8> Pid1 = erlang:list_to_pid("<9172.91.0>").</div><div class=""><9172.91.0></div></div><div class=""><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)9> Pid = Pid1.</div><div class="">** exception error: no match of right hand side value <9172.91.0></div></div><div class=""><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)11> Bin1 = erlang:term_to_binary(Pid1).</div><div class=""><<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,</div><div class=""> 107,80,114,111,46,108,111,99,97,108,0,0,0,…>></div></div><div class=""><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)12> Bin = Bin1.</div><div class="">** exception error: no match of right hand side value </div><div class=""> <<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,</div><div class=""> 107,80,114,111,46,108,111,99,97,108,0,0,0,...>></div><div class="">(<a href="mailto:yao1@MacBookPro.local" target="_blank" class="">yao1@MacBookPro.local</a>)13></div></div><div class=""><br class=""></div><div class=""><div class="">MacBookPro:code by$ erl -name yao2</div><div class="">Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]</div><div class="">Eshell V10.5.3 (abort with ^G)</div><div class="">(<a href="mailto:yao2@MacBookPro.local" target="_blank" class="">yao2@MacBookPro.local</a>)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>>.</div><div class=""><<131,103,100,0,21,121,97,111,50,64,77,97,99,66,111,111,</div><div class=""> 107,80,114,111,46,108,111,99,97,108,0,0,0,...>></div><div class="">(<a href="mailto:yao2@MacBookPro.local" target="_blank" class="">yao2@MacBookPro.local</a>)2> Pid = erlang:binary_to_term(Bin).</div><div class=""><0.91.0></div><div class="">(<a href="mailto:yao2@MacBookPro.local" target="_blank" class="">yao2@MacBookPro.local</a>)3> Pid ! {self(), {echo, 1234}}.</div><div class="">{<0.87.0>,{echo,1234}}</div><div class="">(<a href="mailto:yao2@MacBookPro.local" target="_blank" class="">yao2@MacBookPro.local</a>)4> receive X -> X end.</div><div class="">1234</div><div class="">(<a href="mailto:yao2@MacBookPro.local" target="_blank" class="">yao2@MacBookPro.local</a>)5></div></div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">I hope some internal thoughts can be revealed for this.</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Yao</div><div class=""><br class=""></div></div></div></div></blockquote></div>
</div></blockquote></div><br class=""></body></html>