Список PID в Erlang

Длинная история, короткая, я пытаюсь копировать проблему парикмахера Сна в Erlang.

В моем решении я решил, что для всех процессов, которые ожидают, я поместил бы их в список. Затем после того как случалось так, что процессы поворачиваются, я снял бы тот PID списка.

К сожалению, когда я звоню

length(myListOfPids).

это перестало работать как пример:

length([<0.46.0>]).
* 2: syntax error before: '<'

существует ли способ сохранить PID так, чтобы я мог вспомнить их и обычно использовать их? т.е.

PID ! message

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

=ERROR REPORT==== 1-Jul-2010::05:50:40 ===
Error in process <0.44.0> with exit value:
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}

barber1 является моим модулем, вестибюль является функцией, которая отслеживает, которых ожидают процессы

5
задан Toymakerii 1 July 2010 в 10:15
поделиться

5 ответов

Ввод идентификаторов путем их ввода у меня тоже не работает. Это единственная проблема?

С кодом:

-module(test).
-export([loop/0]).

loop() ->
    receive
        {hello} ->
            io:format("Hello world!~n"),
            loop()
end.

Я получаю:

 Eshell V5.7.5  (abort with ^G)
 1> Pid = spawn(fun test:loop/0).
 <0.35.0>
 2> L = [Pid].
 [<0.35.0>]
 3> length(L). 
 1
6
ответ дан 18 December 2019 в 06:10
поделиться

Вы также можете создать Pid из трех его компонентов, используя pid / 3.

1> длина ([pid (0,35,0)]).

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

Проблема, с которой столкнулась ваша программа, в другом.

{badarg, [{erlang, length, [<0.46.0>]}, {barber1, waitRoom, 2}]}

Вызов erlang: length / 1 создал бадарг. Третий элемент {erlang, length, [<0.46.0>]} - это список аргументов, переданных в erlang: length. Это эквивалентно:

1> erlang: length (pid (0,46,0)).

где вы намеревались:

1> erlang: length ([pid (0,46,0)]).

(Досадно, что оболочка erlang теперь скрывает от вас внутреннее представление ошибок erlang. Заменяя указанную выше ошибку на:

** исключительная ошибка: неверный аргумент в функции length / 1, вызываемый как length (<0.35.0>)

, который намного легче понять, но менее полезен, потому что он мешает изучить важный навык самостоятельной интерпретации ошибок Erlang.)

10
ответ дан 18 December 2019 в 06:10
поделиться

Это сообщение об ошибке:

=ERROR REPORT==== 1-Jul-2010::05:50:40 ===
Error in process <0.44.0> with exit value:
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}

означает, что вы вызывали length (<0.46.0>) , not length ([<0.46.0>]) (игнорируя на данный момент, что PID могут быть только записаны, но не прочитаны). В трассировке стека самая верхняя функция будет иметь список аргументов. Поскольку length принимает один аргумент, этот список имеет единственный аргумент: вы берете длину PID, что, очевидно, не работает, поскольку только списки имеют длину.

5
ответ дан 18 December 2019 в 06:10
поделиться

Проблема в том, что, хотя <0.46.0> - это способ, которым PID выводит напечатанный , он не может быть введен сюда. Вместо этого вы можете использовать list_to_pid ("<0.46.0>") . Конечно, если у вас есть PID (созданный таким образом, возвращенный из spawn и т. Д.), Он может быть сохранен в списке и извлечен, как любой другой термин Erlang.

3
ответ дан 18 December 2019 в 06:10
поделиться

Стандартный способ получить pid - взять возвращаемое значение функции spawn, либо spawn/1, spawn/3, spawn_link/1, spawn_link/3, и proc_lib эквиваленты.

Простой способ записать pid - это функция c:pid/3, вызываемая как c:pid(0,25,0), которая вернет <0.25.0>. Это функция быстрого доступа для оболочки. В противном случае вы можете использовать list_to_pid/1, как упоминал Алексей Романов.

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

Самый чистый способ сделать это - использовать возвращаемое значение функции spawn. Генерирование pid вручную следует оставить только как отладочное решение.

2
ответ дан 18 December 2019 в 06:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: