本文介绍了检查Erlang中的活动计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有一种简单的方法来获取以 erlang:send_after erlang:apply_after 等在Erlang中?

Is there a simple way to get a list of all currently waiting timers started with erlang:send_after, erlang:apply_after, etc. in Erlang?

推荐答案

出于调试目的,您可以使用 dbg :)。

For debugging purposes you can use dbg :).

首先创建一个ets表,该表将存储所有计时器引用。

First create an ets table which will store all timer references.

1> ets:new(timer_dbg, ['public', 'named_table', 'bag']).
timer_dbg

然后创建一个dbg处理程序函数,该函数检查从erlang返回的调用:send_after ,并将返回的计时器参考保存到表中

Then create a dbg handler function, which checks for calls returning from erlang:send_after, and saves the returned timer reference to the table

2> Fun = fun({'trace', _Pid, 'return_from', {erlang, send_after, 3}, Ref}, []) ->
2>           ets:insert(timer_dbg, {Ref}), [];
2>          (_Msg, []) ->
2>           []
2>       end.
#Fun<erl_eval.12.113037538>

将该函数设置为跟踪处理程序。同时在所有进程上启用对 erlang:send_after()的调用

Set the function as trace handler. Also enable matching on the call to erlang:send_after() on all processes

3> dbg:tracer('process', {Fun, []}).
{ok,<0.35.0>}
4> dbg:p('all', 'c').
{ok,[{matched,nonode@nohost,26}]}
5> dbg:tpl(erlang, send_after, [{'_', [], [{'return_trace'}]}]).
{ok,[{matched,nonode@nohost,1},{saved,1}]}

erlang:send_after()

6> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.43>
7> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.47>
8> erlang:send_after(1000, self(), {}).
#Ref<0.0.0.51>

最后检查表中是否包含那些引用:

Finally check that the table does contain those references:

9> ets:tab2list(timer_dbg).
[{#Ref<0.0.0.51>},{#Ref<0.0.0.43>},{#Ref<0.0.0.47>}]

这样,您将存储由任何调用 erlang:send_after()的进程创建的所有计时器引用。 。您可以在 erlang:read_timer()上映射它们,以过滤活动计时器。

This way you will store all timer references ever created by any process ever calling erlang:send_after(). You can map them over erlang:read_timer() to filter the alive timers.

您可以跟踪对 send_after 。也可以在 cancel_timer 上进行匹配,并从表中手动删除已取消的引用。

You can trace calls to send_after in a similar manner. It is also possible to match on cancel_timer and manually remove the cancelled references from the table.

此外,如果您没有消息密集型应用程序,您应该能够匹配那些计时器触发的消息和/或功能,并从列表中删除过期的引用。

Also, if you don't have a message-intensive application, you should be able to match on messages and/or functions triggered by those timers, and remove the expired references from the list.

这篇关于检查Erlang中的活动计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 18:55