gen_server命名为timer_server导致定时器模块功能无法返回

时间:2009-02-01 04:02:30

标签: erlang otp

我创建了一个主管,它产生了gen_server我叫timer_server。此timer_serve r的任务之一是管理注册并调用timer:send_interval以在特定时间间隔内向pid发送消息。

然而,在gen_server的初始化中,我呼叫timer:send_interval我得到了一个锁定。文档说定时器:函数立即返回,所以这非常令人不安。

当我将gen_server重命名为record_timer_server时,此问题已解决。我的问题是两倍:

  1. 为什么我可以创建一个已注册的进程timer_server,如果我的应用程序启动时调用了timer:start()已经有一个进程?
  2. 一旦开始,如果使用timer_server函数调用我的send_interval,为什么这个函数不会导致badmatch找到名称?
  3. 我认为代码不是必需的,但我可以更新以添加一些(如果请求)。

1 个答案:

答案 0 :(得分:3)

这可以简单地通过执行以下操作来重新创建,该调用挂起对timer: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.

返回正常,然后是gen_server:调用timer_server。然后你的过程就会陷入困境,等待自己做出回应。