Muduo网络库的实现TimerQueue定时器(五)

源码下载以及安装点击链接https://blog.youkuaiyun.com/YoungSusie/article/details/90021742

分类 Muduo网络库编程 学习笔记

给前面的EventLoop 加上定时的功能,传统的Reactor 通过控制select 和 poll 的等待时间来实现定时,现在Linux 系统中有了timefd ,可以用和处理IO事件相同的方式来处理定时。

timerfd_create() 函数把时间变为一个文件描述符,该“文件” 在定时器超时的那一刻变得可读,可以融入Reactor 模型中,用同一的方式处理IO 事件和超时事件。

muduo 的定时器功能由三个class实现,TimerId、Timer、 TimerQueue ,用户只能看到TimerId , 另外两个class 是内部实现细节。

TimerQueue 的接口很简单,只有两个函数addTimer() 和 cancel() 。addTimer() 是供给EventLoop 使用的,EventLoop 将其封装为更好的runAt() 、 runAfter() 和 runEvery() 。TimerQueue 的成员函数只能在其所属的IO线程进行调用,因此不需要加锁。

  • TimerQueue 数据结构的选择
    TimerQueue 需要高效地组织尚未到期的Timer, 能快速地根据当前时间找到已经快到期的Timer , 也需要能高效地删除和添加 Timer .一种合适的数据结构是二叉搜索树,把Timer 按照到期时间先后顺序排序,但是不能直接使用map<Timestamp, Timer*> , 因为如果两个同时到期的Timer 应该如何处理?

    • 用multimap 或者multiset
    • 设法区分key , 以pair<Timerstamp,Timer*> 为key。这样即使两个Timer 的到期时间相同,他们的地址也必定不同。
	typedef std::pair<Timestamp,Timer*> Entry;
	typedef std::set<Entry> TimerList;  //记录定时器

在这里插入图片描述

  • 程序代码

==================================TimerQueue.cc ====================================

#define __STD_LIMIT_MACROS
#include "TimerQueue.h"

#include "EventLoop.h"
#include "Timer.h"
#include "TimerId.h"

#include <boost/bind.hpp>
#include <sys/timerfd.h>

int createTimerfd()
{
   
   
	int timerfd = ::timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK | TFD_CLOEXEC);

	if(timerfd < 0)
	{
   
   
		std::cout << "timerfd_create error ";
		_exit(-1);
	}
	return timerfd;
}

struct timespec howMuchTimeFromNow(Timestamp when)
{
   
   	
	int64_t microseconds = when.microSecondsSinceEpoch()-Timestamp::now().microSecondsSinceEpoch();
	if(microseconds < 100) 
	{
   
    microseconds = 100;} 
	struct timespec ts;
	ts.tv_sec = static_cast<time_t>(microseconds / Timestamp::kMicroSecondsPerSecond);//秒
	ts.tv_nsec = static_cast<long>((microseconds % Timestamp::kMicroSecondsPerSecond) * 1000);//纳秒
	return ts;
}

void readTimerfd(int timerfd,Timestamp now)
{
   
   
	uint64_t howmany;
	ssize_t n = ::read(timerfd,&howmany,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值