Эрланг: Почему я не могу зарегистрировать себя ()? - PullRequest
0 голосов
/ 17 марта 2011

Эта строка завершается с исключением 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 ]

5 голосов
/ 17 марта 2011

Если процесс уже зарегистрирован, он выдаст badarg.Есть также некоторые другие случаи, которые вызывают это, например, имя уже используется.См. the erlang: register / 2 docs для получения дополнительной информации.

EDIT

Здорово, что вы разместили код для воспроизведения вашей проблемы.

Итак,При первом вводе pongr/0 вы зарегистрируетесь self().Когда вы получите сообщение, вы обработаете его и снова наберете pongr/0.Во второй раз, когда вы вводите pongr/0, вы пытаетесь зарегистрировать self(), что не удается, потому что оно уже зарегистрировано.

Кроме того, если вы хотите использовать регистрацию большого количества процессов, вам следует заглянуть в gproc.register/2 требует атом в качестве ключа, и существует ограничение в около миллиона атомов, если вы явно не измените его.См. руководство по эффективности .gproc также может работать распределенно и, следовательно, может использоваться вместо global модуля.

5 голосов
/ 17 марта 2011

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>)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...