Kann jemand die Struktur einer Pid (Process Identifier) ​​in Erlang erklären?

69

Kann jemand die Struktur einer Pid in Erlang erklären?

Pids sieht so aus: <A.B.C>zB <0.30.0>, aber ich würde gerne wissen, was die Bedeutung dieser drei "Bits" ist: A, B und C.

'A' scheint auf einem lokalen Knoten immer 0 zu sein, aber dieser Wert ändert sich, wenn sich der Eigentümer der Pid auf einem anderen Knoten befindet.

Ist es möglich, eine Nachricht nur mit der Pid direkt auf einem Remote-Knoten zu senden? So etwas in der Art: <4568.30.0>! Nachricht, ohne den Namen des registrierten Prozesses und den Knotennamen explizit angeben zu müssen ({proc_name, Node}! Message)?

Jideel
quelle
Ok, mein Hauptproblem ist behoben. Ich habe einfach nicht die gute PID an die entfernte Seite geschickt ...
Jideel

Antworten:

77

Gedruckte Prozess-IDs <ABC> bestehen aus 6 :

  • A, die Knotennummer (0 ist der lokale Knoten, eine beliebige Nummer für einen entfernten Knoten)
  • B die ersten 15 Bits der Prozessnummer (ein Index in der Prozesstabelle) 7
  • C, Bits 16-18 der Prozessnummer (dieselbe Prozessnummer wie B) 7

Intern ist die Prozessnummer auf dem 32-Bit-Emulator 28 Bit breit. Die ungerade Definition von B und C stammt aus R9B und früheren Versionen von Erlang, in denen B eine 15-Bit-Prozess-ID und C ein Wrap-Zähler war, der erhöht wurde, als die maximale Prozess-ID erreicht wurde und niedrigere IDs wiederverwendet wurden.

In der Erlang-Verteilung sind die PIDs etwas größer, da sie sowohl das Knotenatom als auch die anderen Informationen enthalten. ( Verteiltes PID-Format )

Wenn eine interne PID von einem Knoten zum anderen gesendet wird, wird sie automatisch in das externe / verteilte PID-Formular konvertiert, sodass das, was auf einem Knoten möglicherweise <0.10.0>( inet_db) ist, möglicherweise so endet, als würde es <2265.10.0>an einen anderen Knoten gesendet. Sie können einfach wie gewohnt an diese PIDs senden.

% 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()]). 

Weitere Informationen finden Sie unter : Interner PID - Struktur , Knoten Erstellungsinformationen , Knoten Erstellung Zähler Interaktion mit EPMD

Archaelus
quelle
1
Es stellte sich heraus, dass ich mich in Bezug auf den Erstellungszähler geirrt hatte, nachdem ich mir die Quelle genau angesehen hatte. Vielen Dank an Wallentin, der mich dazu aufgefordert hat. Ich bin mir jetzt über die Bitgrößen von B und C sicher, habe aber das Makro _GET_BITS in der erts-Quelle nicht vollständig befolgt, also bin ich mir nicht sicher, ob ich mit den oberen und unteren Bits Recht habe.
Archaelus
13

Wenn ich mich richtig erinnere, ist das Format <nodeid,serial,creation>. 0 ist der aktuelle Knoten, ähnlich wie ein Computer immer den Hostnamen "localhost" hat, um auf sich selbst zu verweisen. Dies ist aus altem Speicher, so dass es möglicherweise nicht 100% richtig hart ist.

Aber ja. Sie könnten die PID list_to_pid/1zum Beispiel mit erstellen .

PidString = "<0.39.0>",
list_to_pid(PidString) ! message.

Na sicher. Sie verwenden einfach die Methode, die Sie zum Erstellen Ihres PidString benötigen. Schreiben Sie wahrscheinlich eine Funktion, die sie generiert, und verwenden Sie diese anstelle von PidString wie folgt:

list_to_pid( make_pid_from_term({proc_name, Node}) ) ! message
Jon Gretar
quelle
Hast du diese große rote Warnung gesehen? list_to_pid / 1 Und Sie können auch einfach {proc_name, Node} senden! Nachricht oder Modul global verwenden, wenn Sie globale Namen verwenden möchten.
Hynek-Pichi-Vychodil
Ja .. Kennen Sie diese anderen Methoden. Und das benutze ich. Das war einfach nicht die Frage. :)
Jon Gretar
pid_to_list / 1 nimmt eine pid und gibt ihre Zeichenfolgendarstellung zurück.
Mcandre
Vielen Dank, dass Sie list_to_pid erwähnt haben - genau das, wonach ich gesucht habe. Hier ist ein bisschen mehr Infos dazu (insbesondere, dass Sie es nicht mit externen Pids verwenden können: stackoverflow.com/questions/10475321/… )
BTK
Zu Pid = pid(0,123,0), Pid = list_to_pid("<0.123.0>").
Ihrer Information
8

Die Prozess-ID <ABC> besteht aus:

  • A, Knoten-ID, die nicht beliebig ist, sondern der interne Index für diesen Knoten in dist_entry. (Es ist eigentlich die Atom-Slot-Ganzzahl für den Knotennamen.)
  • B, Prozessindex, der sich auf den internen Index im Proctab bezieht (0 -> MAXPROCS).
  • C, Seriell, das sich jedes Mal erhöht, wenn MAXPROCS erreicht wurde.

Das Erstellungs-Tag von 2 Bits wird nicht in der PID angezeigt, sondern wird intern verwendet und erhöht sich bei jedem Neustart des Knotens.

psyeugenisch
quelle
3

Die PID bezieht sich auf einen Prozess und eine Knotentabelle. Sie können eine Nachricht also nur dann direkt an eine PID senden, wenn sie in dem Knoten bekannt ist, von dem aus Sie den Anruf tätigen.

Möglicherweise funktioniert dies, wenn der Knoten, von dem aus Sie den Anruf tätigen, bereits über den Knoten informiert ist, auf dem der Prozess ausgeführt wird.

Ruben
quelle
1
Wenn ich "node ()" auf dem Remote-Knoten ausgeben möchte, wird mein lokaler Knoten angezeigt, aber ich kann die "Remote-PID" nicht registrieren, da list_to_pid fehlschlägt: "register (client, list_to_pid (" <5058.95.0> ")) . " gibt "schlechtes Argument" zurück. Vermisse ich etwas
Jideel
Sie können nur lokale Pids registrieren. Um Remote-Pids zu registrieren, müssen Sie das globale Registrierungsmodul verwenden (oder Ihr eigenes Registrierungssystem rollen).
Archaelus
0

Abgesehen von dem, was andere gesagt haben, kann dieses einfache Experiment hilfreich sein, um zu verstehen, was intern vor sich geht:

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

Sie können also sehen, dass der Knotenname intern in der PID gespeichert ist. Weitere Informationen finden Sie in diesem Abschnitt von Learn You Some Erlang.

Nacmartin
quelle