Table of Contents
本篇介绍一下定时器。muduo里的定时器也是经过精心设计的(这句话好像有点废)。
1. 使用例子
EventLoop 类提供了4个和定时器相关的接口:
// timers
///
/// Runs callback at 'time'.
/// Safe to call from other threads.
///
TimerId runAt(const Timestamp& time, const TimerCallback& cb);
///
/// Runs callback after @c delay seconds.
/// Safe to call from other threads.
///
TimerId runAfter(double delay, const TimerCallback& cb);
///
/// Runs callback every @c interval seconds.
/// Safe to call from other threads.
///
TimerId runEvery(double interval, const TimerCallback& cb);
///
/// Cancels the timer.
/// Safe to call from other threads.
///
void cancel(TimerId timerId);
- runAt : 在某个时间点执行用户函数
- runAfter : 在N秒后执行用户函数
- runEvery : 每N秒执行用户函数
- cancel : 停止某个定时器的计时
前面3个函数最终都会调用TimerQueue::addTimer(...), 3.1节会详细介绍,cancel() 则会在3.3节讲述。
2.类结构:
muduo的定时器主要由TimerQueue, Timer, TimerId和Timestamp四个类实现,类的关系如下图:
为了很好地复用Eventloop的框架,muduo采用了 timerfd_create / timerfd_gettime / timerfd_settime 系统函数来实现定时器的功能。定时器超时,timer对应的fd变为可读,TimerQueue就执行符合条件的用户函数。
3.实现细节
-
3.1 Add timer
TimerQueue保证timer是按时间先后排序的,插入的timer如果超时时间比已有的timers都要早,则要通过timerfd_settime函数调整timeout的值。
TimerId TimerQueue::addTimer(const TimerCallback& cb,