此行失败并显示badarg
例外:
register(myproc, self()),
文档说self/0
返回一个pid,而register/2
需要一个pid。那是什么给出了什么?
编辑:不,严重的是,它尚未注册,它不是保留原子,当我从过程中注册它时,它可以正常工作产卵吧。
太奇怪了!好的,我得到了更多的线索。当我将呼叫转移到register()
到不同的地方时,有时会有效,有时会中断。这是我的示例代码。在你叫我疯了之前先跑吧。 : - )
-module(pingpong).
-export([start/1, ping/2, pong/0]).
ping(N, Pong_Pid) ->
link(Pong_Pid),
pingr(N, Pong_Pid).
pingr(0, _) ->
io:format("Ping exiting~n", []),
exit(ping);
pingr(N, Pong_Pid) ->
Pong_Pid ! {ping, self()},
receive
pong ->
io:format("Ping received pong~n", [])
end,
pingr(N - 1, Pong_Pid).
pong() ->
%% This one works.
%%register(pong, self()),
process_flag(trap_exit, true),
pongr().
pongr() ->
%% This one fails.
register(pong, self()),
receive
{ping, Ping_PID} ->
io:format("Pong received ping~n", []),
Ping_PID ! pong,
pongr();
{'EXIT', From, Reason} ->
io:format("pong exiting, got ~p~n", [{'EXIT', From, Reason}])
end.
start(Ping_Node) ->
PongPID = spawn(pingpong, pong, []),
spawn(Ping_Node, pingpong, ping, [3, PongPID]).
答案 0 :(得分:5)
myproc已经注册?
第一次调用应该成功,额外的调用将导致badarg异常。
1> register(myproc, self()).
true
2> myproc ! foo.
foo
3> flush().
Shell got foo
ok
4> register(myproc, self()).
** exception error: bad argument
in function register/2
called as register(myproc,<0.30.0>)
答案 1 :(得分:5)
如果该进程已经注册,它将抛出一个badarg。还有一些其他情况会导致这种情况,就像名称已经使用过一样。有关详情,请参阅the erlang:register/2 docs。
修改
发布代码来重现您的问题非常棒。
因此,当您第一次输入pongr/0
时,您将注册self()
。收到消息后,您将对其进行处理并再次致电pongr/0
。第二次输入pongr/0
时,您尝试注册self()
,因为它已经注册而失败了。{/ p>
此外,如果要使用注册大量进程,则应查看gproc
。 register/2
需要一个原子作为键,除非你明确地改变它,否则有大约一百万个原子的限制。请参阅efficiency guide。 gproc
也可以运行分布式,因此可以代替global
模块使用。