名为timer_server的gen_server导致定时器模块函数不返回

发布于 2024-07-13 18:26:25 字数 644 浏览 5 评论 0原文

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

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

当我将 gen_server 重命名为 record_timer_server 时,这个问题就解决了。 那么我的问题有两个:

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

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

I created a supervisor that spawned a gen_server I called timer_server. One of the tasks of this timer_server is to manage registration and call timer:send_interval to send a message to a pid on a certain interval.

However, in the init of the gen_server, where I call timer:send_interval I was getting a lockup. The documentation said the timer: functions return immediately, so this was very troubling.

When I renamed my gen_server to record_timer_server this problem cleared up. My question is two fold then:

  1. Why could I create a registered process timer_server, if there already was one when timer:start() was called by my application starting up?
  2. Once started, why would this function not cause a badmatch finding the name, if it was calling in to my timer_server using the send_interval function?

I don't think code is necessary but I can update to add some if requested.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷清清 2024-07-20 18:26:25

只需执行以下挂在对计时器的调用上即可重新创建: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_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 的调用。 然后您的进程就会陷入等待自身响应的状态。

This can be recreated simply by doing the following which hangs on the call to timer:send_interval.

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

While this fails...

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>]},

So, it seems that the first call to timer tries to start a process called timer_server, and hangs if you've taken this name first.

As to why it hangs timer.erl does:

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.

which returns fine, followed by a gen_server:call to timer_server. Your process then gets stuck waiting for itself to respond.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文