当前位置: 首页 > news >正文

项目模块七:TimerWheel模块

一、模块设计思想

在之前介绍了 Linux 定时器,详见具备技术一:Linux定时器-CSDN博客,所以这个模块的实现就是把 Linux 的定时器和时间轮任务队列整合在一起,来实现设置一个定时器,操控时间轮任务何时执行过期事件,来达到最终目的:对于超时连接的释放

timerfd:实现每隔一段时间给进程一个超时事件。

timerwheel:每次执行 RuntimeTask 都可执行一波到期定时任务,要实现一个完整秒级定时器就要整合两个模块。

二、子模块一:TimerTask

详见具备技术一:Linux定时器-CSDN博客,由于只是一个任务,所以一点没有改变,真正要改变的是子模块二。

三、子模块二:TimerWheel

1、设计思路

要与 EventLoop 模块结合就一定要绑定一个 eventloop,由于需要和 timerfd 结合,所以还要有 timerfd,为了能够读取定时器里面的数据,所以要 poller 来管理文件描述符 timerfd,并且绑定读写回调函数用于读出事件就绪次数,便于处理事件。

2、成员变量

int timerfd:定时器文件描述符,用于读取写入就绪的事件并通知。

EventLoop *_loop:绑定一个 eventloop,用于线程安全处理事件。

unique_ptr<Channel> _timer_channel:用 Channel 管理 timerfd 就绪事件。

int _tick:指针指向哪里哪里的任务就超时要执行。

int _capacity:最大延迟时间

vector<vector<PtrTask>> _wheel:二维数组

unordered_map<uint64_t, WeakTask> _timers:辅助shared_ptr

3、成员函数

(1)私有函数1:删除定时任务 void RemoveTimer(int id)

找到哈希表里面的定时任务并删除。

auto pos = _timers.find(id);

_timers.erase(pos);

(2)私有函数2:创建定时器 int CreateTimerfd()

步骤:先创建 timerfd,然后再设置 timerfd 的超时时间

返回值:返回定时器文件描述符。原理:每隔一个超时时间系统会给描述符写入一个8字节数据代表已经超时几次。

clockid:

CLOCK_REALTIME:以系统时间作为基准值(若改变系统时间就会不准确)

CLOCK_MONOTONIC:系统启动时间进行递增的基准值(准确)

flags:0代表阻塞操作,TFD_NONBLOCK非阻塞操作。

fd:timerfd_create 返回值

flags:0表示相对时间

struct itimerspec:

new value:这次设置的超时时间。

old value:用于保存上次的超时时间

最后返回创建好的 timerfd

(3)私有函数3:读取定时器里面的超时次数 int ReadTimerfd()

用 read

注意:读写都是用8字节的数据!

(4)私有函数4:执行一次超时任务 void RunTask()

就是把存放任务的 vector 数组里面的任务清空,若任务真的被销毁了就会调用析构函数里面的超时连接释放函数。

(5)私有函数5:timerfd读回调函数 void OnTime()

先从 ReadTimerfd() 里面获取要执行几次超时任务,再 for 循环执行 RunTask()

(6)私有函数6:线程安全添加超时事件 void TImerAddInLoop(uint64_t id, uint32_t delay,const Task &task)

就是正常的添加事件,因为是私有接口,等到公有接口定义函数的时候才考虑线程安全。

(7)私有函数7:线程安全刷新定时任务 void TimerRefreshInLoop(uint64_t id)

同上

(8)私有函数8:线程安全删除定时任务 void TimerCancledLoop(uint64_t id)

同上

(9)公有函数1:构造函数

首先需要绑定一个 eventloop,然后一定要创建 timerfd,用 Channel 管理 timerfd,然后设置私有函数里面的 tiemrfd 读回调函数,最后开启 timerfd 读事件关心。一个步骤不能少!!!!!

(10)公有函数2,3,4:线程安全添加 / 刷新 / 删除定时任务

由于要用到 EventLoop 里面的 RunInLoop 函数来线程安全的执行添加 / 刷新 / 删除定时任务,所以不能在 TimerWheel 类的公有函数里面定义,而要在全局里面定义

(11)公有函数5:确定是否有指定任务 bool HasTask(uint64_t id)

在哈希表里面找一下有没有指定任务即可。

四、代码展示


http://www.mrgr.cn/news/57698.html

相关文章:

  • 操作系统笔记(二)进程,系统调用,I/O设备
  • 数字化技术如何加速精益生产策略的实施与成效?
  • Ubuntu 安装Mysql+Redis+Nginx
  • 最好的ppt模板网站是哪个?做PPT不可错过的18个网站!
  • ElasticSearch-7.17.10集群升级至ElasticSearch-7.17.24
  • 视频云存储/音视频流媒体视频平台EasyCVR视频汇聚平台在欧拉系统中启动失败是什么原因?
  • IEEE 802.3-2012 Clause 22.2.4.2
  • NacosException: Client not connected, current status:STARTING异常解决
  • 在线制作拼团活动步骤是什么
  • java线程池大小与CPU关系
  • Unity插件-Intense TPS 讲解
  • 【Kubernetes实战】Kubernetes集群搭建(虚拟机环境,一主两从)
  • Pandas 文件读取与保存指南:高效处理 CSV、Excel 等多种格式数据
  • 【算法设计与分析】-回溯法的回忆-学习【期末复习篇章】
  • 绘画相关,MIDI
  • js中for...in 和 for...of 区别
  • java生成可执行文件
  • Java中的反射是什么?如何使用反射API?
  • 回归模型的增量学习的经典文章和方法
  • Docker原理|实战
  • globalAlpha:深入解析Canvas中的全局透明度
  • package,json 文件中依赖包的说明
  • 项目管理必备Git使用及关键指令(总体结构 + 必要步骤)教你如何协同开发
  • 微信小程序的日期区间选择组件的封装和使用
  • 如何使用IP代理优化亚马逊平台的操作体验
  • Get-WmiObject 命令使用