Question

Quelqu'un peut-il expliquer la structure d'un Pid à Erlang?

Pids ressemble à ceci: <A.B.C> , par exemple. < 0,30.0 > , mais j'aimerais savoir quelle est la signification de ces trois & "; bits &"; : A, B et C.

'A' semble toujours être 0 sur un nœud local, mais cette valeur change lorsque le propriétaire du Pid est situé sur un autre nœud.

Est-il possible d'envoyer directement un message sur un nœud distant en utilisant uniquement le PID? Quelque chose comme ça: & Lt; 4568.30.0 & Gt; ! Message, sans avoir à spécifier explicitement le nom du processus enregistré et le nom du noeud ({proc_name, Node}! Message)?

Était-ce utile?

La solution

Identifiants de processus imprimés < A.B.C & Gt; sont composés de 6 :

  • A, le numéro du noeud (0 est le local noeud, un nombre arbitraire pour un noeud distant)
  • B, les 15 premiers bits du numéro de processus (un index dans la table de processus) 7
  • C, bits 16-18 du numéro de processus (le même numéro de processus que B) 7

En interne, le numéro de processus a une largeur de 28 bits sur l’émulateur 32 bits. La définition étrange de B et C provient de R9B et des versions antérieures d’Erlang dans lesquelles B était un ID de processus 15 bits et C était un compteur intégré incrémenté lorsque l’ID de processus maximum était atteint et que des ID inférieurs étaient réutilisés.

Dans la distribution erlang, les PID sont un peu plus grands car ils incluent l’atome de noeud ainsi que les autres informations. ( format PID distribué )

Lorsqu'un PID interne est envoyé d'un nœud à un autre, il est automatiquement converti au format PID externe / distribué. Ainsi, ce qui pourrait être <0.10.0> (inet_db) sur un nœud peut devenir <2265.10.0> lorsque envoyé à un autre noeud. Vous pouvez simplement envoyer à ces PID normalement.

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

Pour plus d'informations, consultez: Interaction de la création de nœuds avec EPMD

Autres conseils

Si je me souviens bien de cela, le format est <nodeid,serial,creation>. 0 est le nœud actuel un peu comme un ordinateur a toujours le nom d'hôte & "; Localhost &"; se référer à lui-même. Ceci est dû à l’ancienne mémoire, il est donc possible que ce ne soit pas correct à 100%.

Mais oui. Vous pouvez construire le pid avec list_to_pid/1 par exemple.

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

Bien sûr. Vous utilisez simplement la méthode dont vous avez besoin pour construire votre PidString. Probablement écrire une fonction qui la génère et l’utiliser à la place de PidString comme ceci:

list_to_pid( make_pid_from_term({proc_name, Node}) ) ! message

Identificateur de processus < A.B.C & Gt; est composé de:

  • Identifiant de noeud qui n'est pas arbitraire mais l'index interne de ce noeud dans dist_entry. (Il s’agit en fait du nombre entier d’emplacement d’atome pour le nom du nœud.)
  • B, index de processus qui fait référence à l’index interne du proctab, (0 - > MAXPROCS).
  • C, Série qui augmente chaque fois que MAXPROCS est atteint.

La balise de création de 2 bits ne s'affiche pas dans le pid mais est utilisée en interne et augmente à chaque redémarrage du nœud.

Le PID fait référence à un processus et à une table de nœuds. Vous ne pouvez donc envoyer un message directement à un PID que s'il est connu dans le noeud à partir duquel vous effectuez l'appel.

Il est possible que cela fonctionne si le noeud avec lequel vous passez l'appel sait sur le nœud sur lequel le processus est exécuté.

Outre ce que d'autres ont dit, vous pouvez trouver cette expérience simple utile pour comprendre ce qui se passe en interne:

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

Ainsi, vous pouvez voir que le nom du noeud est stocké en interne dans le pid. Plus d'informations dans cette section de Learn You Some Erlang.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top