誰かがErlangのPidの構造を説明できますか?
Pidsは次のようになります:<A.B.C>
、例えば<0.30.0>、しかし、私はこれらの3つの「ビット」の意味が何であるか知りたいです:A、BおよびC。
ローカルノードでは「A」は常に0のようですが、Pidの所有者が別のノードにある場合、この値は変化します。
Pidだけを使用してリモートノードに直接メッセージを送信することはできますか?そのようなもの:<4568.30.0>!メッセージ。登録済みプロセスの名前とノード名を明示的に指定する必要はありません({proc_name、Node}!Message)?
印刷されたプロセスID <A.B.C>は 6 で構成されます:
内部的には、32ビットエミュレータのプロセス番号は28ビット幅です。 BとCの奇妙な定義は、R9Bと以前のバージョンのErlangから来ています。Bは15ビットのプロセスIDで、Cは最大プロセスIDに達し、より低いIDが再利用されたときにインクリメントされるラップカウンターです。
アーラン分布では、ノードatomおよびその他の情報を含むため、PIDは少し大きくなります。( 分散PID形式 )
内部PIDが1つのノードから別のノードに送信されると、自動的に外部/分散PID形式に変換されるため、<0.10.0>
(inet_db
)1つのノードで<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構造 、 ノード作成情報 、 EPMDとのノード作成カウンターの相互作用
これを正しく覚えている場合、形式は<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
プロセスID <A.B.C>は以下で構成されます:
2ビットの作成タグはpidには表示されませんが、内部的に使用され、ノードが再起動するたびに増加します。
PIDはプロセスとノードテーブルを参照します。したがって、呼び出し元のノードでPIDがわかっている場合にのみ、PIDに直接メッセージを送信できます。
これは、呼び出し元のノードがすでに 知っている プロセスが実行されているノードである場合に機能する可能性があります。
他の人が言ったこととは別に、この簡単な実験は、内部で何が起こっているのかを理解するのに役立ちます。
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に格納されていることを確認できます。 Learn More Some Erlangの このセクション の詳細情報。