Erlang中的PID列表

时间:2010-07-01 10:15:54

标签: concurrency erlang list process

长话短说我试图在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是我的模块,waitingRoom是跟踪哪些进程正在等待的函数

5 个答案:

答案 0 :(得分:10)

你也可以使用pid / 3从它的三个组件构建一个Pid。

1&GT;长度([PID(0,35,0)])。

请注意,如果您在与创建Pid的节点不同的节点上构建pid,则使用这些技术构建Pid会出错。

你的程序遇到的问题是不同的。

{badarg,[{二郎,长度,并[d 0.46.0&GT;]},{barber1,候车室,2}]}

对erlang的调用:length / 1创建了一个badarg。 {erlang,length,[&lt; 0.46.0&gt;]}的第三个元素是传递给erlang:length的参数列表。所以这相当于:

1&GT;二郎:长度(PID(0,46,0))

你想要的地方:

1&GT;二郎:长度([PID(0,46,0)])

(令人讨厌的是,erlang shell现在隐藏了erlang对你的错误的内部表示。用以下代码替换上面的错误:

**异常错误:函数长度/ 1中的错误参数称为长度(&lt; 0.35.0&gt;)

这更容易理解但不太有用,因为它妨碍了自己学习解释erlang错误的基本技能。)

答案 1 :(得分:6)

通过输入Pids输入Pids对我来说也不起作用。 这是唯一的问题吗?

使用代码:

-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

答案 2 :(得分:5)

此错误消息:

=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 :(得分:3)

问题是虽然<0.46.0>是PID 打印的方式,但它不能以这种方式输入。您可以改用list_to_pid("<0.46.0>")。当然,一旦你有了PID(以这种方式创建,从spawn返回等),它就可以存储在列表中并像任何其他Erlang术语一样被检索。

答案 4 :(得分:2)

获取pid的标准方法是获取生成函数的返回值,spawn/1spawn/3spawn_link/1spawn_link/3和{{ 1}}等价物。

记下pid的一种简单方法是使用函数c:pid / 3,称为proc_lib,它将返回c:pid(0,25,0)。这是shell的快捷功能。否则,您可以使用Alexey Romanov提到的<0.25.0>

但是,在尝试手动构建pid之前,您应该了解pid的作用。 pid充当进程的个人标识符,并且仅供了解它的人使用。如果你手上还没有pid,那么你可能不应该拥有它。间接地,这意味着导致程序的不同部分的绝缘 - 只关心您产生的那些部分,并让程序的每个部分都关注自己的业务。

最简单的方法是使用spawn函数的返回值。 手动生成pid只能作为调试解决方案。