Список PID в Эрланге - PullRequest
       29

Список PID в Эрланге

5 голосов
/ 01 июля 2010

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

В своем решении я решил, что для всех процессов, которые ожидают, я бы поместил их в список.Затем, когда произойдет поворот этих процессов, я уберу этот 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 - это мой модуль, waitRoom - функция, которая сохраняетотслеживать, какие процессы ожидают

Ответы [ 5 ]

10 голосов
/ 01 июля 2010

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

1> length ([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: длина (pid (0,46,0)).

, где вы предполагали:

1> erlang: длина ([pid (0,46,0)]).

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

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

, который гораздо проще понять, но менее полезен, поскольку он мешает усвоить необходимый навык интерпретации ошибок эрланга самостоятельно.)

6 голосов
/ 01 июля 2010

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

С кодом:

-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
5 голосов
/ 01 июля 2010

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

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

3 голосов
/ 01 июля 2010

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

2 голосов
/ 01 июля 2010

Стандартный способ получения 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 действует как личный идентификатор процесса и предназначен для использования только теми, кто знает о нем. Если у вас в руке уже нет пиджа, то, скорее всего, вы уже не должны им владеть. Косвенно это должно привести к изоляции различных частей программы & mdash; заботятся только о тех битах, которые вы породили, и каждая часть вашей программы занимается своими делами.

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

...