Muduo网络库源码分析之定时器的实现

本文详细分析了muduo网络库中定时器的实现,涉及TimerId、Timer和TimerQueue三个关键类。TimerId用于唯一标识定时器,Timer封装超时参数及回调,TimerQueue管理所有定时器并实现高效添加和删除。采用timerfd结合Channel和EventLoop处理超时事件,确保高精度和低延迟。此外,还介绍了如何在EventLoop中添加和注销定时器,以及timerfd的基本操作和C API。
摘要由CSDN通过智能技术生成

muduo 的定时器功能由三个 class 实现,TimerId、Timer 和 TimerQueue。

TimerId 类

它唯一标识一个 Timer 定时器。TimerId Class 同时保存Timer* 和 sequence_,这个 sequence_ 是每个 Timer 对象有一个全局递增的序列号 int64_t sequence_,用原子计数器(AtomicInt64)生成。
它主要用于注销定时器,这样就可以区分地址相同的先后两个 Timer 对象。

namespace muduo
{
namespace net
{

class Timer;

///
/// An opaque identifier, for canceling Timer.
///
/* 带有唯一标识的Timer,主要用于取消Timer */
class TimerId : public muduo::copyable
{
 public:
  TimerId()
    : timer_(NULL),
      sequence_(0)
  {
  }

  TimerId(Timer* timer, int64_t seq)
    : timer_(timer),    //timer 定时器的指针
      sequence_(seq)    //seq 该定时任务的序列号
  {
  }

  // default copy-ctor, dtor and assignment are okay

  friend class TimerQueue;

 private:
  Timer* timer_;
  int64_t sequence_;
};

}
}

Timer 类

封装了定时器的一些参数,包括超时时间(expiration_)、超时回调函数(callback_)、时间间隔(interval_)、是否重复定时(repeat_)、定时器的序列号等成员变量,成员函数大都是返回这些变量的值,run() 用来调用回调函数,restart() 用来重启定时器。

Timer.h

namespace muduo
{
namespace net
{
///
/// Internal class for timer event.
///
/* 定时器 */
class Timer : boost::noncopyable
{
 public:
  Timer(const TimerCallback& cb, Timestamp when, double interval)
    : callback_(cb),
      expiration_(when),
      interval_(interval),
      repeat_(interval > 0.0),
      sequence_(s_numCreated_.incrementAndGet())
  { }

#ifdef __GXX_EXPERIMENTAL_CXX0X__
  Timer(TimerCallback&& cb, Timestamp when, double interval)
    : callback_(std::move(cb)),
      expiration_(when),
      interval_(interval),
      repeat_(interval > 0.0),
      sequence_(s_numCreated_.incrementAndGet())
  { }
#endif

  void run() const
  {
    callback_();    //执行定时器回调函数
  }

  /* 返回定时器的超时时间戳 */
  Timestamp expiration() const  { return expiration_; }
  /* 是否周期性定时 */
  bool repeat() const { return repeat_; }
  /* 返回本定时器的序列号 */
  int64_t sequence() const { return sequence_; }

  /* 重启定时器 */
  void restart(Timestamp now);

  static int64_t numCreated() { return s_numCreated_.get(); }

 private:
  const TimerCallback callback_;    //超时回调函数
  Timestamp expiration_;            //超时时间戳
  const double interval_;           //时间间隔,如果是一次性定时器,该值为0
  const bool repeat_;               //是否重复执行
  const int64_t sequence_;          //本定时任务的序号

  static AtomicInt64 s_numCreated_; //定时器计数,当前已经创建的定时器数量
};
}
}

Timer.cc

#include <muduo/net/Timer.h>

using namespace muduo;
using namespace muduo::net;

AtomicInt64 Timer::s_numCreated_;

void Timer::restart(Timestamp now)
{
  if (repeat_)
  {
      //如果需要重复,那就将时间设为下次超时的时间
    expiration_ = addTime(now, interval_);
  }
  else
  {
      //如果不需要重复,那就将超时时间设为一个不可用的 value
    expiration_ = Timestamp::invalid();
  }
}

TimerQueue 类

定时器队列,用于管理所有的定时器,此类的接口只有两个:添加和注销定时器,分别为 addTimer()cancel()

TimerQueue 数据结构的选择。需要高效地组织目前尚未到期的 Timer,能快速地根据当前时间找到已经到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值