Erlang 中的 PID 列表
长话短说,我正在尝试在 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 是跟踪哪些进程正在等待的函数
Long story short I am trying to replicate the Sleeping barber problem in Erlang.
In my solution I decided that for all the processes that are waiting I would put them into a list. Then, once it was that processes turn, I would take that PID off of the list.
Unfortunately when I call
length(myListOfPids).
it fails, as an example:
length([<0.46.0>]).
* 2: syntax error before: '<'
is there a way to store PID's so that I can recall them and use them normally? i.e.
PID ! message
... just in case it matters here is the actual error I recieve when running my program:
=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 is my module, waitingRoom is the function that keeps track of which processes are waiting
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您还可以使用 pid/3 从三个组件构建一个 Pid。
1>长度([pid(0,35,0)])。
请注意,如果您在与创建 pid 的节点不同的节点上构造 pid,则使用任何一种构造 Pid 的技术都会出错。
您的程序遇到的问题是不同的。
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}
对 erlang:length/1 的调用创建了一个 badarg。 {erlang,length,[<0.46.0>]} 的第三个元素是传递给 erlang:length 的参数列表。所以这相当于:
1> erlang:长度(pid(0,46,0))。
您想要的位置:
1> erlang:length([pid(0,46,0)]).
(令人烦恼的是,erlang shell 现在向您隐藏了 erlang 的内部错误表示。将上述错误替换为:
** 异常错误:函数 length/1 中的错误参数称为 length(<0.35.0>)
这更容易理解但不太有用,因为它妨碍了你自己学习解释 erlang 错误的基本技能。)
You can also construct a Pid from it's three components using pid/3.
1> length([pid(0,35,0)]).
Be aware that using any of these techniques for constructing Pid goes wrong if you construct a pid on a different node than the one it was created on.
The problem your program is having is different.
{badarg,[{erlang,length,[<0.46.0>]},{barber1,waitingRoom,2}]}
A call to erlang:length/1 created a badarg. The third element of {erlang,length,[<0.46.0>]} is the list of arguments passed to erlang:length. So that's equivalent to:
1> erlang:length(pid(0,46,0)).
where you intended:
1> erlang:length([pid(0,46,0)]).
(Annoyingly, the erlang shell now hides erlang's internal representation of errors from you. Replacing the above error with:
** exception error: bad argument in function length/1 called as length(<0.35.0>)
which is much easier to understand but less useful because it gets in the way of learning the essential skill of interpreting erlang errors yourself.)
通过键入 Pids 来输入它们对我来说也不起作用。
这是唯一的问题吗?
使用代码:
我得到:
Entering Pids by typing them does not work for me either.
Is that the only problem?
With code:
I get:
此错误消息:
表示您正在调用
length(<0.46.0>)
,不是length([<0.46.0>])
code>(暂时忽略 PID 只能写入,不能读取)。在堆栈跟踪中,最顶层的函数将具有参数列表。由于length
采用一个参数,因此该列表只有一个参数:您正在采用 PID 的长度,这显然会失败,因为只有列表才有长度。This error message:
means that you were calling
length(<0.46.0>)
, notlength([<0.46.0>])
(ignoring for the moment that PIDs can only be written, not read). In the stack trace the topmost function will have the list of arguments. Sincelength
takes one argument, this list has a single argument: you are taking the length of a PID, which obviously fails, since only lists have lengths.问题是,虽然
<0.46.0>
是PID打印的方式,但不能以这种方式输入。您可以使用list_to_pid("<0.46.0>")
代替。当然,一旦你有了 PID(以这种方式创建,从spawn
返回,等等),它就可以存储在列表中并像任何其他 Erlang 术语一样检索。The problem is that while
<0.46.0>
is the way that a PID gets printed, it can't be entered this way. You can uselist_to_pid("<0.46.0>")
instead. Of course, once you do have a PID (created in this way, returned fromspawn
, etc.), it can be stored in a list and retrieved like any other Erlang term.获取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>
。这是 shell 的快捷函数。否则,您可以使用 Alexey Romanov 提到的list_to_pid/1
。然而,在尝试手动构建 pid 之前,您应该了解 pid 的作用。 pid 充当进程的个人标识符,仅供了解它的人使用。如果您手中还没有 pid,那么您可能不应该已经拥有它。间接地,这意味着导致程序的不同部分的隔离——只关心您生成的那些部分,并让程序的每个部分关注自己的业务。
因此,最简洁的方法是使用生成函数的返回值。 手动生成 pid 应该仅作为调试解决方案。
The standard way to get a pid is to take the return value of a spawn function, either
spawn/1
,spawn/3
,spawn_link/1
,spawn_link/3
, and theproc_lib
equivalents.A simple way to write down a pid is with the function c:pid/3, called like
c:pid(0,25,0)
, which will return<0.25.0>
. That's a shortcut function for the shell. Otherwise, you can uselist_to_pid/1
as mentioned by Alexey Romanov.However, you should be aware of the role of pids before trying to build them by hand. The pid acts as the personal identifier of a process and is meant to be used only by those who know about it. If you don't have the pid in your hand already, then you likely shouldn't be in its possession already. Indirectly, this is meant to lead to insulation of different parts of a program — only care about those bits that you spawned and have each part of your program mind its own business.
The cleanest way to do it is thus to use the return value of a spawn function. Generating a pid by hand should be left as a debugging solution only.