muduo定时器由 定时器类定义,由定时器队列来维护
//Timer.h/.cc
class Timer : noncopyable
{
...
private:
const TimerCallback callback_; //定时器回调函数
Timestamp expiration_; //下一次超时时刻
const double interval_; //超时时间间隔,如果是一次性定时器,该值为0
const bool repeat_; //是否重复
const int64_t sequence_; //定时器序号
static AtomicInt64 s_numCreated_; //已创建的计数器数量
}
//TimerQueue.h/cc
class TimerQueue : noncopyable
{
private:
typedef std::pair<Timestamp, Timer*> Entry;
typedef std::set<Entry> TimerList;
typedef std::pair<Timer*, int64_t> ActiveTimer;
typedef std::set<ActiveTimer> ActiveTimerSet;
//TimeList和ActiveTimeSet都保存的是时间列表,一个是按照时间戳排序,一个是按定时器地址排序
std::vector<Entry> getExpired(Timestamp now);// 返回超时的定时器列表
ActiveTimerSet cancelingTimers_; //被取消的定时器
}
定时器回调函数
void TimerQueue::handleRead()
{
...
std::vector<Entry> expired = getExpired(now);
callingExpiredTimers_ = true;
cancelingTimers_.clear();
// safe to callback outside critical section
for (const Entry& it : expired)
{
it.second->run();
}
callingExpiredTimers_ = false;
//因为已经从activeTimers_中移除,如果不是一次性定时器,则需重启
reset(expired, now);
}
std::vector<TimerQueue::Entry> TimerQueue::getExpired(Timestamp now)
{
assert(timers_.size() == activeTimers_.size());
std::vector<Entry> expired;
//<now, 地址> 这里地址取最大的哨兵值
Entry sentry(now, reinterpret_cast<Timer*>(UINTPTR_MAX));
//返回第一个未到期的timers的迭代器
//lower_bound的含义是返回第一个“值大于等于sentry”的元素的迭代器,即*end >= sentry
//由于pair比较大小按照first/second的顺序
//且Entry的元素重载了> < 运算符,由于sentry的value必定大于 *end.value
//所以now 一定小于 end->first(不可能=)
TimerList::iterator end = timers_.lower_bound(sentry);
assert(end == timers_.end() || now < end->first);
//将到期定时器插入expired中(插入迭代器)
std::copy(timers_.begin(), end, back_inserter(expired));
timers_.erase(timers_.begin(), end);
//从activeTimers_中移除到期的定时器
for (const Entry& it : expired)
{
ActiveTimer timer(it.second, it.second->sequence());
size_t n = activeTimers_.erase(timer);
}
return expired;
}