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

StackOverflow https://stackoverflow.com/questions/243363

  •  04-07-2019
  •  | 
  •  

Вопрос

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

Пиды выглядят так: <A.B.C> , например<0.30.0>, но мне хотелось бы знать, что означают эти три «бита»:А, Б и С.

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

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

Это было полезно?

Решение

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

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

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

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

Когда внутренний PID отправляется с одного узла на другой, он автоматически преобразуется во внешнюю/распределенную форму PID. <0.10.0> (inet_db) на одном узле может закончиться как <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()]). 

Для получения дополнительной информации см.: Внутренняя структура ПИД-регулятора, Информация о создании узла, Взаимодействие счетчика создания узла с EPMD

Другие советы

Если я правильно помню это, то формат <nodeid,serial,creation>. 0 является текущим узлом, так же как компьютер всегда имеет имя хоста & Quot; localhost & Quot; ссылаться на себя. Это старая память, поэтому она не может быть на 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

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

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

Двухбитовый тег создания не отображается в pid, но используется внутри и увеличивается при каждом перезапуске узла.

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

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

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

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. Дополнительную информацию можно найти в этом разделе раздела "Изучите вас на некоторых языках Erlang".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top