一. timer简介
- 定时器
简单而言,一个定时器(timer),就是在定义的超时时间过后主动去执行指定的超时处理函数的组件 - 定时器典型使用场景
定时器(timer)是网络通信必不可少的一个组件,在复杂的网络环境下,端到端通信时有失败。一个典型的使用场景是,A主机发送写文件指令到B主机,B主机收到写请求后开始写,但由于环境原因B主机上出现IO-hang并且不可恢复,此时B主机的写线程会一直阻塞,当然也不会主动回复写结果给A主机;此时A主机能做的就只有傻傻等待,进而造成读写阻塞,白白的浪费自己的系统资源。而如果A发送请求到B时在A上启动一个timer,此问题便可以缓解。此时,A和B之间的一次同步通信就有两种终止方式,一种是B回复写结果给A,A终止同步通信,另一种是A上设置的定时器超时即在期望时间内B未回复写结果给A,A认为要么网络异常要么B已挂,此时A就可以直接关闭同步连接,进而继续去处理其他任务。
二. libev中的timer
- libev原生支持定时器功能,底层通过堆来管理多个定时器,效率较高。linux下,通过epoll来精准的控制定时时间,支持毫秒级定时器
libev中定义了定时器相关的结构:
struct ev_timer
,通过此结构来实现定时时间和超时回调函数的绑定/* shared by all watchers */ #define EV_WATCHER(type) \ int active; /* private */ \ int pending; /* private */ \ EV_DECL_PRIORITY /* private */ \ EV_COMMON /* rw */ \ EV_CB_DECLARE (type) /* private */ #define EV_WATCHER_TIME(type)\ EV_WATCHER (type)\ ev_tstamp at; /* private */ /* invoked after a specific time, repeatable (based on monotonic clock) */ /* revent EV_TIMEOUT */ typedef struct ev_timer { EV_WATCHER_TIME (ev_timer); ev_tstamp repeat; /* rw */ } ev_timer;
- libev中对timer的底层数据结构支持
- 通过堆来管理诸多定时器,又同时支持二叉树实现的最小堆和四叉树实现的最小堆
- libev中定义了专门操作定时器的相关函数
- ev_timer_set
绑定超时时间和重复增量时间到ev_timer - ev_timer_init
初始化timer,绑定超时回调函数到ev_timer中,调用ev_timer_set
,绑定定时时间,指定timer在第一次超时后的增量超时设定时间 - ev_timer_start
置ev_timer状态为激活状态,将ev_timer结构添加到ev_loop中的timers数组中,并且对在timers中建立的小顶堆结构进行调整维护 - ev_timer_stop
置ev_timer状态为非激活状态,从timers数组中删除ev_timer对象,并且对在timers中建立的小顶堆结构进行调整维护 - ev_timer_again
如果timer是激活状态,则判断ev_timer结构中的repeat
项是否为0,如果是,则直接调用ev_timer_stop
停止timer,否则对timer的下次超时时间进行调整并对timers堆进行调整;如果timer为未激活状态,则判断ev_timer结构中的repeat
是否为0,若不为0,则设置timer时间为repeat
指定时间,并且调用ev_timer_start
启动timer - ev_timer_remaining
返回距离下次timeout超时所剩余的时间
- ev_timer_set
- 定时实现