You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
intuv_timer_start(uv_timer_t*handle,
uv_timer_cbcb,
uint64_ttimeout,
uint64_trepeat) {
uint64_tclamped_timeout;
if (cb==NULL)
returnUV_EINVAL;
if (uv__is_active(handle))
uv_timer_stop(handle);
clamped_timeout=handle->loop->time+timeout; //用loop的当前时间加上过期时间为真正的调用时间if (clamped_timeout<timeout)
clamped_timeout= (uint64_t) -1; // 如果真正的调用时间要小于过期时间则设置调用时间为最大数值handle->timer_cb=cb;
handle->timeout=clamped_timeout;
handle->repeat=repeat;
/* start_id is the second index to be compared in uv__timer_cmp() */handle->start_id=handle->loop->timer_counter++; //设定此timer的唯一idheap_insert(timer_heap(handle->loop),
(structheap_node*) &handle->heap_node,
timer_less_than); //二叉堆操作(最小堆,可以快速取出过期时间最短的timer句柄)uv__handle_start(handle); // 向loop中注册活动句柄return0;
}
uv_timer_t声明
直接从uv.h切入,很容易就能找到
uv_timer_s
结构体声明:其中
UV_HANDLE_FIELDS
为所有句柄的抽象基础宏,在上一篇文章介绍过,在这里不做过多介绍。我们主要看一下timer的私有宏UV_TIMER_PRIVATE_FIELDS
,由于平台的差异,我们在这里只对unix.h中的timer私有宏进行介绍:下面是结构体内部数据结构的介绍:
timer_cb
定时器的回调函数heap_node
二叉堆的指针,分别指向left、right和parenttimeout
过期时间,在timeout
毫秒之后,指定的timer_cb
会被调用repeat
间隔时间,回调函数在第一次timeout
毫秒调用之后会间隔repeat
毫秒进行调用start_id
定时器启动时候注册的id,如果定时器的触发时间是一致的,会对比start_id
来判别先后顺序timer相关API
uv_timer_init
视线挪到timer.c中:
对基础句柄进行初始化,并设定句柄类型(h-> type)为
UV_TIMER
从而实现对定时器句柄的初始化。uv_timer_start
在
uv_timer_start
中,分别对timer的回调函数、过期时间、间隔时间进行了设定。在这里简单介绍一下为什么会有如下这个判断:libuv会每次事件循环的伊始通过
uv_update_time()
来更新handle->loop->time
。但是如果调用方在独立使用
uv_timer_start
的时候,忘记先调用uv_update_time()
则会造成如上这种判断的情况。而libuv开发者没有把uv_update_time()
写入到uv_timer_start
中则是为了保证libuv时间循环的性能。uv__run_timers
此函数供event-loop调用,其中有一点需要注意的地方:
uv_timer_stop
和uv_timer_again
在这里不做过多介绍,通过函数名就能大概明白具体是做什么的。而为何要在timer回调运行之前对timer进行停止和下一次调用的注册,则是为了防止handle->timer_cb
回调阻塞时间过长,导致每次uv_timer_again
会逐渐增大repeat timers
回调触发的时间。node中对uv_timer_t的应用
由于之前在《node源码粗读》系列对Timers API进行过详尽的分析,所以在这里主要是借对
uv_timer_t
的分析串一下,在node中的调用函数如下:通过如上代码可以得知,node的上下文环境,全部是通过
uv_handle_t
中的handle->data
传递到timer_cb
中的,回调最终在刚才所讲到的uv__run_timers
中的handle->timer_cb(handle);
触发运行。by 小菜
The text was updated successfully, but these errors were encountered: