Qualcuno può spiegare la struttura di un Pid in Erlang?
Domanda
Qualcuno può spiegare la struttura di un Pid in Erlang?
Pids è simile al seguente: <A.B.C>
, ad es. lt &; 0.30.0 gt &; , ma vorrei sapere qual è il significato di questi tre " bit " : A, B e C.
'A' sembra essere sempre 0 su un nodo locale, ma questo valore cambia quando il proprietario del Pid si trova su un altro nodo.
È possibile inviare direttamente un messaggio su un nodo remoto usando solo il Pid? Qualcosa del genere: & Lt; 4568.30.0 & Gt; ! Messaggio, senza dover specificare in modo esplicito il nome del processo registrato e il nome del nodo ({proc_name, Node}! Message)?
Soluzione
ID processo stampati < A.B.C & Gt; sono composti da 6 :
- A, il numero del nodo (0 è il locale nodo, un numero arbitrario per un nodo remoto)
- B, i primi 15 bit del numero di processo (un indice nella tabella del processo) 7
- C, bit 16-18 del numero di processo (lo stesso numero di processo di B) 7
Internamente, il numero di processo ha una larghezza di 28 bit sull'emulatore a 32 bit. La strana definizione di B e C deriva da R9B e versioni precedenti di Erlang in cui B era un ID processo a 15 bit e C era un contatore a capo incrementato quando veniva raggiunto l'ID processo massimo e venivano riutilizzati ID inferiori.
Nella distribuzione erlang i PID sono leggermente più grandi in quanto includono l'atomo del nodo e le altre informazioni. ( Formato PID distribuito )
Quando un PID interno viene inviato da un nodo all'altro, viene automaticamente convertito nel modulo PID esterno / distribuito, quindi ciò che potrebbe essere <0.10.0>
(inet_db
) su un nodo potrebbe finire con <2265.10.0>
quando inviato a un altro nodo. Puoi semplicemente inviare a questi PID normalmente.
% 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()]).
Per ulteriori informazioni, consultare: Interazione contatore creazione nodi con EPMD
Altri suggerimenti
Se lo ricordo correttamente, il formato è <nodeid,serial,creation>
.
0 è il nodo corrente, proprio come un computer ha sempre il nome host & Quot; localhost & Quot; riferirsi a se stesso. Questo è dovuto alla vecchia memoria, quindi potrebbe non essere corretto al 100%.
Ma sì. È possibile creare il pid con list_to_pid/1
ad esempio.
PidString = "<0.39.0>",
list_to_pid(PidString) ! message.
Certo. Basta usare qualsiasi metodo sia necessario per costruire il tuo PidString. Probabilmente scrivi una funzione che la genera e usa quella invece di PidString in questo modo:
list_to_pid( make_pid_from_term({proc_name, Node}) ) ! message
ID processo < A.B.C & Gt; è composto da:
- A, ID nodo che non è arbitrario ma l'indice interno per quel nodo in dist_entry. (In realtà è l'intero numero di slot dell'atomo per il nome del nodo.)
- B, indice di processo che si riferisce all'indice interno nel proctab, (0 - > MAXPROCS).
- C, seriale che aumenta ogni volta che MAXPROCS è stato raggiunto.
Il tag di creazione di 2 bit non viene visualizzato nel pid ma viene utilizzato internamente e aumenta ogni volta che il nodo viene riavviato.
Il PID fa riferimento a un processo e una tabella dei nodi. Quindi è possibile inviare un messaggio direttamente a un PID solo se è noto nel nodo da cui si effettua la chiamata.
È possibile che funzioni se il nodo da cui si effettua la chiamata è già sa circa il nodo su cui è in esecuzione il processo.
A parte ciò che altri hanno detto, potresti trovare questo semplice esperimento utile per capire cosa sta succedendo internamente:
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>>
Quindi, puoi vedere che il nome del nodo è memorizzato internamente nel pid. Maggiori informazioni in questa sezione di Learn You Some Erlang.