【sylar】框架篇-Chapter8-定时器模块

本文详细介绍了sylar C++高性能分布式服务器框架中定时器的实现,采用基于时间堆的最小堆策略,实现毫秒级精度的定时任务调度。定时器支持相对时间注册、条件触发、循环执行等功能,并能应对系统时间调整带来的影响。此外,文章还展示了关键代码实现,包括Timer类和TimerManager类的内部逻辑。

站在巨人的肩膀上

C++高性能分布式服务器框架

从零开始重写sylar C++高性能分布式服务器框架

概述

  • 基于 epoll_wait 超时实现定时器功能,精度毫秒级,支持在指定超时时间结束之后执行回调函数。
  • sylar 使用时间堆的方式管理定时器。
    • 设计定时器的另一种实现思路是直接将超时时间当作 tick 周期,具体操作是每次都取出所有定时器中超时时间最小的超时值作为一个 tick,这样,一旦 tick 触发,超时时间最小的定时器必然到期。处理完已超时的定时器后,再从剩余的定时器中找出超时时间最小的一个,并将这个最小时间作为下一个 tick,如此反复,就可以实现较为精确的定时。
    • 最小堆很适合处理这种定时方案,将所有定时器按最小堆来组织,可以很方便地获取到当前的最小超时时间,sylar 采取的即是这种方案。
    • sylar 实现最小堆的方法是利用了自定义比较函数的 std::set。
  • 所有定时器根据绝对的超时时间点进行排序,每次取出离当前时间最近的一个超时时间点(getNextTimer 函数),计算出超时需要等待的时间,然后等待超时。超时时间到后,获取当前的绝对时间点,然后把最小堆里超时时间点小于这个时间点的定时器都收集起来(listExpiredCb 函数),执行它们的回调函数。

Timer

  • 定时器类。
  • 内含绝对时间点、是否循环执行的标识、回调函数等。
  • 内含定时器比较仿函数 Comparator,比较的依据是两个定时器的绝对时间。

TimerManager

  • 定时器管理器。
  • 内含存放定时器的 std::set。

其他说明

  • 在注册定时事件时,提供的是相对时间。sylar 会根据传入的相对时间和当前的绝对时间计算出定时器超时时的绝对时间点(在 Timer 的构造函数里面计算出绝对时间),然后根据这个绝对时间点对定时器进行最小堆排序。因为依赖的是系统绝对时间,所以需要考虑校时因素。
  • sylar 支持创建条件定时器,也就是在创建定时器时绑定一个变量,在定时器触发时判断一下该变量是否仍然有效(通过 std::weak_ptr 实现),如果变量无效,那就取消触发。
  • 关于 onTimerInsertedAtFront() 方法的作用。这个方法是 IOManager 提供给 TimerManager 使用的,当 TimerManager 检测到新添加的定时器的超时时间比当前最小的定时器还要小时,TimerManager 通过这个方法来通知 IOManager 立刻更新当前的 epoll_wait 超时,否则新添加的定时器的执行时间将不准确。实际实现时,只需要在 onTimerInsertedAtFront() 方法内执行一次 tickle 就行了,tickle 之后,epoll_wait 会立即退出,并重新从 TimerManager 中获取最近的超时时间,这时拿到的超时时间就是新添加的最小定时器的超时时间了。
  • sylar 的定时器以 gettimeofday() 来获取绝对时间点并判断超时,所以依赖于系统时间,如果系统进行了校时,比如 NTP 时间同步,那这套定时机制就失效了。sylar 的解决办法是设置一个较小的超时步长,比如 3 秒钟,也就是 epoll_wait 最多 3 秒超时,假设最近一个定时器的超时时间是 10 秒以后,那 epoll_wait 需要超时 3 次才会触发。每次超时之后除了要检查有没有要触发的定时器,还顺便检查一下系统时间有没有被往回调。如果系统时间往回调了1个小时以上,那就触发全部定时器。

部分相关代码

/**
 * @filename    timer.h
 * @brief   定时器模块
 * @author  L-g
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值