Может кто-нибудь объяснить структуру Пида в Эрланге?

Может кто-нибудь объяснить структуру Pid в Erlang?

Pids выглядит так: <A.B.C>, например. < 0.30.0 > , но я хотел бы знать, что означает эти три "бита": A, B и C.

'A' всегда всегда 0 на локальном node, но это значение изменяется, когда владелец Pid находится на другом node.

Можно ли напрямую отправить сообщение на удаленный node, используя только Pid? Что-то вроде этого: < 4568.30.0 > ! Сообщение, без необходимости явно указывать имя зарегистрированного процесса и имя node ({proc_name, Node}!)?

Ответ 1

Печатные идентификаторы процессов < A.B.C > состоят из 6:

  • A, номер node (0 - локальный node, произвольное число для удаленного node)
  • B, первые 15 бит номера процесса (индекс в таблице процессов) 7
  • C, бит 16-18 номера процесса (тот же номер процесса, что и B) 7

Внутренний номер процесса составляет 32 бита в 32-разрядном эмуляторе. Нечетное определение B и C происходит из R9B и более ранних версий Erlang, в которых B был идентификатором процесса 15 бит, а C - счетчиком обхода, увеличивающимся при достижении максимального идентификатора процесса, и более низкие идентификаторы были повторно использованы.

В распределении erlang PID немного больше, поскольку они включают атом node, а также другую информацию. (Распределенный формат PID)

Когда внутренний PID отправляется из одного node в другой, он автоматически преобразуется во внешнюю/распределенную форму PID, поэтому то, что может быть <0.10.0> (inet_db) на одном node, может закончиться как <2265.10.0> при отправке на другой node. Вы можете просто отправить эти 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 console.
io:format(RemoteUser, "Hello from ~p~n", [node()]). 

Для получения дополнительной информации см. Внутренняя структура PID, Node информация о создании, Node взаимодействие счетчика создания с EPMD

Ответ 2

Если я правильно это помню, формат <nodeid,serial,creation>. 0 является текущим node, как компьютер всегда имеет имя хоста "localhost", чтобы ссылаться на себя. Это по старой памяти, поэтому она не может быть на 100% правильной.

Но да. Вы можете построить pid с помощью list_to_pid/1, например.

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

Конечно. Вы просто используете любой метод, который вам нужен для создания PidString. Вероятно, напишите функцию, которая ее генерирует, и используйте это вместо PidString следующим образом:

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

Ответ 3

Идентификатор процесса < A.B.C > состоит из:

  • A, node id, который не является произвольным, а внутренним индексом для node в dist_entry. (На самом деле это целое число слота атома для имени node.)
  • B, индекс процесса, который ссылается на внутренний индекс в proctab, (0 → MAXPROCS).
  • C, Serial, который увеличивается при каждом достижении MAXPROCS.

Тег создания 2 бита не отображается в pid, но используется внутри и увеличивается при каждом перезапуске node.

Ответ 4

ПИД-код относится к процессу и таблице node. Таким образом, вы можете отправлять сообщение только на PID, если оно известно в node, из которого вы выполняете вызов.

Возможно, что это будет работать, если node вы выполняете вызов уже знает о node, на котором процесс выполняется.

Ответ 5

Помимо того, что говорили другие, вы можете найти этот простой эксперимент полезным для понимания того, что происходит внутри:

1> node().
[email protected]
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>>

Итак, вы можете указать, что имя node внутренне хранится в pid. Дополнительная информация в в этом разделе Learn You Some Erlang.