1.Timer类(每个抽象定时器对象)
成员变量:
构造函数:
以上是对各个成员变量的初始化
- std::move()
- 当超时时间间隔 interval_ 大于0时,即为重复定时器
- 定时器序号通过原子操作增加
2.TimerQueue类
成员变量:
- timerfd_:定时器文件描述符
- timerfdChannel_:管理定时器事件(Channel类:负责注册与响应IO 事件)
- timers_、activeTimers_ 都是保存的Timer类对象,前者通过超时时刻进行排序,后者通过Timer类对象地址进行排序
- 也可改为unorder_map<Timestamp, Timer*> TimerList; unorder_map<Timer*, Timestamp> TimerList;
成员函数:
addTimer()函数定义如下:
此时我们暂且将 loop->runInLoop()注释掉,只是简单的调用addTimerInLoop()函数,该函数定义如下:
insert()函数定义如下:
插入的定时器超时时刻如果比当前 timers_ 中的最小超时时刻还要小,将earliestChanged = true
更新 timers_、activeTimers_
如果 earliestChanged = true,则调用 resetTimerfd()函数,更新定时器文件描述符对应的超时时刻
小结:
一个TimerQueue类对象通过::timerfd_create()只创建了一个定时器文件描述符,通过std::set来管理自定义抽象定时器对象Timer,插入一个新的抽象定时器对象时,若它的超时时刻比当前定时器文件描述符对应的超时时刻小,即更早到期,则更新定时器文件描述符对应的超时时刻
cancle()函数定义如下:
此时我们依旧暂且将 loop->runInLoop()注释掉,只是简单的调用cancelInLoop()函数,该函数定义如下:
我们再来看一下其构造函数:
- 设置回调函数 handleRead()
- timerfdChannel_.enableReading();的调用时序图如下:
最终结果就是将定时器事件添加到poll()、epoll()中- 在handelRead()回调函数中调用了169行的 getExpired()函数来获取超时定时器