2

我创建了一个主管,它产生了一个gen_server我称为timer_server. 这个timer_server 的任务之一是管理注册和调用timer:send_interval以在某个时间间隔向 pid 发送消息。

但是,在gen_server我调用的 init 中,timer:send_interval我被锁定了。文档说计时器:函数立即返回,所以这很麻烦。

当我重命名我gen_serverrecord_timer_server这个问题时,这个问题就解决了。我的问题是两个方面:

  1. 如果我的应用程序启动timer_server时已经有一个注册进程,为什么我可以创建一个注册进程?timer:start()
  2. 一旦启动,为什么这个函数不会导致错误匹配找到名称,如果它正在调用我timer_server使用该send_interval函数?

我认为代码不是必需的,但如果需要,我可以更新以添加一些代码。

4

1 回答 1

3

这可以通过执行以下挂起对计时器的调用来重新创建:send_interval。

1> register(timer_server, self()).
true
2> timer:send_interval(5000, self(), hello).

虽然这失败了......

1> timer:send_interval(5000, self(), hello).
{ok,{interval,#Ref<0.0.0.32>}}
2> register(timer_server, self()).
** exited: {badarg,[{erlang,register,[timer_server,<0.30.0>]},

因此,似乎第一次调用 timer 会尝试启动一个名为 timer_server 的进程,如果您先使用此名称,则会挂起。

至于为什么它挂起 timer.erl 确实:

ensure_started() ->
    case whereis(timer_server) of
        undefined -> 
            C = {timer_server, {?MODULE, start_link, []}, permanent, 1000, 
                worker, [?MODULE]}
            supervisor:start_child(kernel_safe_sup, C),  % kernel_safe_sup
            ok;
        _ -> ok
    end.

返回正常,然后是对 timer_server 的 gen_server:call。然后,您的进程会卡住等待自己响应。

于 2009-02-01T09:05:34.380 回答