有一个简单的方式来获得所有当前正在等待计时器的名单开始erlang:send_after,erlang:apply_after等在二郎山?
出于调试目的,您可以使用dbg:).
首先创建一个ets表,它将存储所有计时器引用.
1> ets:new(timer_dbg, ['public', 'named_table', 'bag']).
timer_dbg
Run Code Online (Sandbox Code Playgroud)
然后创建一个dbg处理函数,它检查从erlang:send_after返回的调用,并将返回的计时器引用保存到表中
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>
Run Code Online (Sandbox Code Playgroud)
将该函数设置为跟踪处理程序.还可以在呼叫上erlang:send_after()启用所有进程的匹配
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}]}
Run Code Online (Sandbox Code Playgroud)
做一些测试电话 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>
Run Code Online (Sandbox Code Playgroud)
最后检查表是否包含这些引用:
9> ets:tab2list(timer_dbg).
[{#Ref<0.0.0.51>},{#Ref<0.0.0.43>},{#Ref<0.0.0.47>}]
Run Code Online (Sandbox Code Playgroud)
这样,您将存储由任何进程调用创建的所有计时器引用erlang:send_after().您可以映射它们erlang:read_timer()以过滤活动计时器.
您可以send_after以类似的方式跟踪呼叫.也可以匹配cancel_timer并手动删除表中取消的引用.
此外,如果您没有消息密集型应用程序,则应该能够匹配这些计时器触发的消息和/或函数,并从列表中删除过期的引用.
这是一个 hack,但使用:ets:tab2list(timer_tab)。对于两个计时器,它包含:
ets:tab2list(timer_tab).
[{{1288384968923398,#Ref<0.0.0.30>},
timeout,
{erlang,integer_to_list,[23]}},
{{23334621698390115688,#Ref<0.0.0.189>},
timeout,
{erlang,integer_to_list,[23]}}]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1796 次 |
| 最近记录: |