Erlang中PID列表

5
长话短说,我正在尝试在Erlang中复制“睡眠理发师问题”。
在我的解决方案中,我决定对于所有正在等待的进程,将它们放入一个列表中。然后,在该进程轮到时,我会将该PID从列表中删除。
不幸的是,当我调用时,
length(myListOfPids).

举个例子,IT失败了:

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个回答

10

你也可以使用pid/3从其三个组件构造一个Pid。

1> length([pid(0,35,0)]).

请注意,如果在创建它的节点之外的节点上构造pid,则使用任何这些构造Pid的技术都会出错。

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

{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,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 shell现在隐藏了erlang错误的内部表示形式。将上述错误替换为:

** exception error: bad argument in function length/1 called as length(<0.35.0>)

虽然更易理解,但对学习自己解释erlang错误的基本技能有所障碍。)


6

通过输入PID来进行操作对我也不起作用。

这是唯一的问题吗?

使用以下代码:

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

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

I get:

 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
这个错误信息:
=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
问题在于虽然<0.46.0>是PID被打印的方式,但不能以此方式输入PID。你可以使用list_to_pid("<0.46.0>")来代替。当然,一旦你拥有了PID(通过这种方式创建,从spawn返回等),它就可以像任何其他Erlang术语一样存储在列表中并检索出来。

2
获取 pid 的标准方式是使用生成函数的返回值, 例如 spawn/1, spawn/3, spawn_link/1, spawn_link/3proc_lib 函数族。一个简单的写法是使用 c:pid/3 函数,调用方式如 c:pid(0,25,0),将返回 <0.25.0>,这是 shell 的快捷方式。否则,您可以像 Alexey Romanov 提到的那样使用 list_to_pid/1 函数。
但是,在尝试手动构建 pid 之前,您应该了解 pid 的作用。Pid 作为进程的个人标识符,仅供知道它的人使用。如果您还没有 pid,请不要拥有它。间接地,这旨在导致程序的不同部分被隔离 - 只关心您生成的那些部分,并使程序的每个部分都自行处理自己的事务。
因此,最清洁的方法是使用生成函数的返回值。手动生成 pid 应仅作为调试解决方案而保留。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接