【问题标题】:gen_server named timer_server caused timer module functions to not return名为 timer_server 的 gen_server 导致定时器模块函数不返回
【发布时间】:2010-10-04 18:01:10
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: erlang erlang-otp


    【解决方案1】:

    这可以通过执行以下挂起对计时器的调用来重新创建: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:call 到 timer_server。然后,您的进程会卡住等待自己响应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2020-04-02
      相关资源
      最近更新 更多