web-dev-qa-db-ja.com

誰かがErlangのPidの構造を説明できますか?

誰かがErlangのPidの構造を説明できますか?

Pidsは次のようになります:<A.B.C>、例えば<0.30.0>、しかし、私はこれらの3つの「ビット」の意味が何であるか知りたいです:A、BおよびC。

ローカルノードでは「A」は常に0のようですが、Pidの所有者が別のノードにある場合、この値は変化します。

Pidだけを使用してリモートノードに直接メッセージを送信することはできますか?そのようなもの:<4568.30.0>!メッセージ。登録済みプロセスの名前とノード名を明示的に指定する必要はありません({proc_name、Node}!Message)?

63
jideel

印刷されたプロセスID <A.B.C>は 6 で構成されます:

  • A、ノード番号(0はローカルノード、リモートノードの任意の番号)
  • B、プロセス番号の最初の15ビット(プロセステーブルへのインデックス) 7
  • C、プロセス番号のビット16〜18(Bと同じプロセス番号) 7

内部的には、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とのノード作成カウンターの相互作用

69
archaelus

これを正しく覚えている場合、形式は<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
13
Jon Gretar

プロセスID <A.B.C>は以下で構成されます:

  • A、任意のノードIDではなく、dist_entryのそのノードの内部インデックス。 (実際には、atomスロット整数です。)
  • B、proctabの内部インデックスを参照するプロセスインデックス(0-> MAXPROCS)。
  • C、MAXPROCSに達するたびに増加するシリアル。

2ビットの作成タグはpidには表示されませんが、内部的に使用され、ノードが再起動するたびに増加します。

8
psyeugenic

PIDはプロセスとノードテーブルを参照します。したがって、呼び出し元のノードでPIDがわかっている場合にのみ、PIDに直接メッセージを送信できます。

これは、呼び出し元のノードがすでに 知っている プロセスが実行されているノードである場合に機能する可能性があります。

2
Ruben

他の人が言ったこととは別に、この簡単な実験は、内部で何が起こっているのかを理解するのに役立ちます。

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の このセクション の詳細情報。

0
nacmartin