Длинная история, короткая, я пытаюсь копировать проблему парикмахера Сна в 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 является моим модулем, вестибюль является функцией, которая отслеживает, которых ожидают процессы
Ввод идентификаторов путем их ввода у меня тоже не работает. Это единственная проблема?
С кодом:
-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
Вы также можете создать 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.)
Это сообщение об ошибке:
=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, что, очевидно, не работает, поскольку только списки имеют длину.
Проблема в том, что, хотя <0.46.0>
- это способ, которым PID выводит напечатанный , он не может быть введен сюда. Вместо этого вы можете использовать list_to_pid ("<0.46.0>")
. Конечно, если у вас есть PID (созданный таким образом, возвращенный из spawn
и т. Д.), Он может быть сохранен в списке и извлечен, как любой другой термин Erlang.
Стандартный способ получить 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 вручную следует оставить только как отладочное решение.