此行失败,但有badarg异常:
register(myproc, self()),
Run Code Online (Sandbox Code Playgroud)
文档说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]).
Run Code Online (Sandbox Code Playgroud)
小智 6
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>)
Run Code Online (Sandbox Code Playgroud)
如果该进程已经注册,它将抛出一个badarg.还有一些其他情况会导致这种情况,就像名称已经使用过一样.有关更多信息,请参阅erlang:register/2文档.
编辑
你发布代码来重现你的问题真是太棒了.
因此,您第一次进入pongr/0时将注册self().当您收到消息时,您将处理它并pongr/0再次呼叫.第二次输入pongr/0时尝试注册self(),但由于已经注册,因此失败.
此外,如果您想使用注册大量进程,您应该查看gproc.register/2需要一个原子作为关键,并且存在大约一百万个原子的限制,除非你明确地改变它.请参阅效率指南.gproc也可以运行分布式,因此可以用来代替global模块.