修改本机的系统时间对send_after的影响

前几天写了一个系统, 在本机(win7系统)自测时,为了测试方便,修改了本机的系统时间(将时间向未来调),但是随后,出现了诡异的bug,费了一段时间后,才发现原因:

修改系统时间之前,原本是每分钟触发一次的逻辑,在修改了系统时间后,每分钟可能会触发一次,但也可能会触发两次!

通过调试打印信息,发现当某分钟内触发两次时,是有规律的,一次是在该分钟的0秒,另一次是在该分钟的59秒。

 

程序的逻辑很简单,就是一个gen_server的模块,在init()时, 调用schedule_loop(),预定一个下一分钟的loop消息,在收到loop消息后,调用schedule_loop()以再次预定一个下一分钟的loop消息,并做相应处理,依此循环下去。

如下是schedule_loop()的实现:

schedule_loop() ->
    {_Hour, _Min, Sec} = erlang:time(),
    Intv =  60 - Sec,
    erlang:send_after(Intv*1000, self(), loop).

如下是收到loop消息对应的处理函数:

handle_info(loop, State) ->
    schedule_loop(),
    loop_handle(),
    {noreply, State};

 

修改系统时间为什么会产生这种影响? erlang:send_after()的实现原理是如何的? 目前还不清楚,以后有时间再研究下底层,这里先mark一下,以后得留心!

 

=========================

后记(2016.9.22):

看了LYSE的最后一章后,明白了原因:

将操作系统的时间向未来调之后, erlang内部的定时器相应地会有一点加速(time correction),R18之前可通过+c 参数设置,

"Time correction in versions prior to 18.0, if undesired, can be turned off by passing the +c argument to the Erlang VM".

具体可以看:  http://learnyousomeerlang.com/time

  

  

posted @ 2016-04-18 12:04  kamfon  阅读(417)  评论(0编辑  收藏  举报