c/c++ linux后台开发学习笔记 3.2.3 定时器

定时器应用

  • 心跳检测
  • 技能冷却
  • 倒计时
  • 定时任务
  • 超时机制

概述

服务器定时器两种实现:

  1. 网络时间和事件时间在一个线程中处理
    • epoll_wait时timeout设成最近一个定时器的时间
  2. 网络时间和事件时间在不同线程中处理
    • 多开一个线程专门处理定时任务,没任务时调用sleep

接口设计

// 初始化定时器
void init_timer();
// 添加定时器
Node* add_timer(int expire, callback cb);
// 删除定时器
bool del_timer(Node* node);
// 找到最近要发⽣的定时任务
Node* find_nearest_timer();
// 更新检测定时器
void update_timer();
// 清除定时器
void clear_timer();

数据结构方案

要求能快速查找最小节点

  • 最小堆 O(logn)
  • 红黑树 O (logn)
  • 时间轮 O(1)

红黑树

时间(key)相同怎么处理?

  1. 加一个很小的offset
  2. key相等的用链表接上
  3. 让红黑树的实现不要求key相等,每次总是把key相等的插在原来的右子节点

最小堆

完全平衡二叉树,比红黑树更快,内存占用小,缺点是不能快速查找/删除任意元素

时间轮

减少无效检测,每次查找的时候找到的总是有效的事件(类似哈希表,以触发时间为key)

单层时间轮

数组长度必须大于最长的定时
每个格子代表一个单位时间(可以是秒,或者五秒,十秒…)
每隔单位时间,把指针往后移动一格,处理当前各自里所有事件
在这里插入图片描述

多层级时间轮

适用于不同定时任务之间定时长度相差很大的情况(比如一个几秒触发一次,一个每个月触发一次),作用是节省内存
在这里插入图片描述
把第一层想成时钟的秒针,第二次是分针,第三层是时针…
只有一分钟以内的任务会被放在第一层,大于等于一分钟小于一小时的被放在第二层…
每次第n层的指针移动,会把当前各自里的所有事件移动到下面几层(重新映射)

参考资料

零声教育c/c++ linux后台开发 3.2.3

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值