muduo_net库源码分析(四)

对应p28
完全理清思路后,感觉实现方式真的很厉害!

基本结构

在这里插入图片描述
在这里插入图片描述

个人理解

这里我觉得的重点如下:
一.Timer类其实并没有实现定时的功能,只是记录了定时任务的设置参数:
在这里插入图片描述
二.核心的定时器实现部分为:
注意,当TimerList为空时,earliestChanged也为true。
在这里插入图片描述

核心的定时功能是在TimerQueue::resetTimerfd中调用::timerfd_settime实现的:
在这里插入图片描述

三.一个EventLoop对象中有一个TimerQueue对象(组合关系),每个TimerQueue对象中也记录了所属的EventLoop对象。
EventLoop类中:

 boost::scoped_ptr<TimerQueue> timerQueue_;

TimerQueue类中:

EventLoop* loop_;		// 所属EventLoop,一个TimerQueue对象只属于一个EventLoop对象

四.一个定时器文件描述符timerfd_管理多个timer对象,但是每次只能满足一个timer对象(TimerList中的timer对象按到期时间排序,所以满足的也就是TimerList中的第一个timer对象)。

五.获取超时定时器列表的原因:
所有timer对象都放在TimerList(set集合)中。因为一个timerfd_每次只能满足一个timer对象(TimerList中的timer对象按到期时间排序,所以满足的也就是TimerList中的第一个timer对象)。
但是TimerList中的某些timer对象也有可能到期时间是相同的,所以当timerfd_满足的那个timer对象超时时,还要判断其他timer对象是否也超时了。

六.TimerQueue的构造函数,里面主要完成了这么几件事:
1.调用::timerfd_create创建定时器文件描述符timerfd_。
2.注册IO事件,即创建Channel对象。
3.在构造函数函数体中添加定时器读事件关注,并设置定时器读事件到来时触发的回调函数。
在这里插入图片描述
七.TimerQueue中的Channel与TimerQueue是组合关系。
八.TimerId类是外部类,对外可见;Timer类和TimerQueue类是内部类,对外隐藏。

调用顺序

添加定时器

EventLoop::runAt–>TimerQueue::addTimer–>TimerQueue::addTimerInLoop

删除定时器

EventLoop::cancel–>TimerQueue::cancel–>TimerQueue::cancelInLoop

源码

Timer.h

#ifndef MUDUO_NET_TIMER_H
#define MUDUO_NET_TIMER_H

#include <boost/noncopyable.hpp>

#include <muduo/base/Atomic.h>
#include <muduo/base/Timestamp.h>
#include <muduo/net/Callbacks.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())
  {
    }

  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_;		// 定时器计数,当前已经创建的定时器数量
};
}
}
#endif  // MUDUO_NET_TIMER_H

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
  {
   
    expiration_ = Timestamp::invalid();
  }
}

TimerId.h

#ifndef MUDUO_NET_TIMERID_H
#define MUDUO_NET_TIMERID_H

#include <muduo/base/copyable.h>

namespace muduo
{
   
namespace net
{
   

class Timer;

///
/// An opaque identifier, for canceling Timer.
///
class TimerId : public muduo::copyable
{
   
 public:
  TimerId()
    : timer_(NULL),
      sequence_(0)
  {
   
  }

  TimerId(Timer* timer, int64_t seq)
    : timer_(timer),
      sequence_(seq)
  {
   
  }

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

  friend class TimerQueue;

 private:
  Timer* timer_;
  int64_t sequence_;
};

}
}

#endif  // MUDUO_NET_TIMERID_H

TimerQueue.h

// This is an internal header file, you should not include this.

#ifndef MUDUO_NET_TIMERQUEUE_H
#define MUDUO_NET_TIMERQUEUE_H

#include <set>
#include <vector>

#include <boost/noncopyable.hpp>

#include <muduo/base/Mutex.h>
#include <muduo/base/Timestamp.h>
#include <muduo/net/Callbacks.h>
#include <muduo/net/Channel.h>

namespace muduo
{
   
namespace net
{
   

class 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值