Erlang:为什么我不能注册self()?

时间:2011-03-17 01:09:50

标签: erlang

此行失败并显示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]).

2 个答案:

答案 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>

此外,如果要使用注册大量进程,则应查看gprocregister/2需要一个原子作为键,除非你明确地改变它,否则有大约一百万个原子的限制。请参阅efficiency guidegproc也可以运行分布式,因此可以代替global模块使用。