muduo网络库学习--定时器

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值