原创作者: mryufeng
阅读:3440次
评论:1条
更新时间:2011-06-01
对于任何网络程序来讲,定时器管理都是重头戏。erlang更是依赖于定时器。基础的timer主要是由time.c erl_time_sup.c实现。timer是基于time wheel的实现,支持time jump detection and correction。 上层的erl_bif_timer.c io.c中实现。
erl +c
Disable compensation for sudden changes of system time.
Normally, erlang:now/0 will not immediately reflect sudden changes in the system time, in order to keep timers (including receive-after) working. Instead, the time maintained by erlang:now/0 is slowly adjusted towards the new system time. (Slowly means in one percent adjustments; if the time is off by one minute, the time will be adjusted in 100 minutes.)
When the +c option is given, this slow adjustment will not take place. Instead erlang:now/0 will always reflect the current system time. Note that timers are based on erlang:now/0. If the system time jumps, timers then time out at the wrong time.
erlang使用timer有3中方式:
1. 语法层面的 receive ... after ...
这个是opcode实现的,一旦timeout立即把process加到调度队列,使用频度比较高。
2. bif
erlang:send_after(Time, Dest, Msg) -> TimerRef
erlang:start_timer(Time, Dest, Msg) -> TimerRef
这个一旦timeout就给Dest发送一条消息,使用频度不是很高。
3.driver层面的。
int driver_set_timer(ErlDrvPort port, unsigned long time);
inet_driver大量使用这个api. tcp/udp进程需要超时处理,所以有大量的连接的时候这种timer的数量非常大。定时器超时后把port_task加到调度队列。
定时器的最早超时时间用于poll的等待时间。
整个定时器由bump_timer来驱动。bump_timer是在schedule的时候不定期调用的。总之使用timer的时候要小心,因为timer实在scheduler的线程里面调用的,不能做非常耗时的操作,否则会阻塞调度器。
erl +c
Disable compensation for sudden changes of system time.
Normally, erlang:now/0 will not immediately reflect sudden changes in the system time, in order to keep timers (including receive-after) working. Instead, the time maintained by erlang:now/0 is slowly adjusted towards the new system time. (Slowly means in one percent adjustments; if the time is off by one minute, the time will be adjusted in 100 minutes.)
When the +c option is given, this slow adjustment will not take place. Instead erlang:now/0 will always reflect the current system time. Note that timers are based on erlang:now/0. If the system time jumps, timers then time out at the wrong time.
erlang使用timer有3中方式:
1. 语法层面的 receive ... after ...
这个是opcode实现的,一旦timeout立即把process加到调度队列,使用频度比较高。
2. bif
erlang:send_after(Time, Dest, Msg) -> TimerRef
erlang:start_timer(Time, Dest, Msg) -> TimerRef
这个一旦timeout就给Dest发送一条消息,使用频度不是很高。
3.driver层面的。
int driver_set_timer(ErlDrvPort port, unsigned long time);
inet_driver大量使用这个api. tcp/udp进程需要超时处理,所以有大量的连接的时候这种timer的数量非常大。定时器超时后把port_task加到调度队列。
定时器的最早超时时间用于poll的等待时间。
整个定时器由bump_timer来驱动。bump_timer是在schedule的时候不定期调用的。总之使用timer的时候要小心,因为timer实在scheduler的线程里面调用的,不能做非常耗时的操作,否则会阻塞调度器。
1 楼 xiao_maijia 2010-05-07 12:01