一种基于最小堆和epoll的高性能定时器——时间堆

(1)时间堆的原理

    定时器以到期时间作为排序值,存放于最小堆这种数据结构中。时间堆不以固定的频率来查询是否有定时器到期,而是每次当堆顶的定时器到期后才处理一次定时事件,避免了定期查询导致的开销。

 (2)难点分析及解决思路

Q:如何确定堆顶定时器是否到期?

A:仍然以定时的方式来提醒进程或线程有定时器到期,但定时时长是变化的,其值始终等于堆顶定时器到期的绝对时刻,与定时时刻之差;

Q:当插入一个新的定时器,或删除一个定时器后,堆顶定时器可能会发生变化,因此定时时长也就可能变化,如何及时更新定时时长呢?

A:借助epoll来监听,插入或删除定时器这一事件是否发生,一旦发生,则立即修改定时时长;

Q:如何实现定时呢?

A:可以使用alarm函数实现。但其实可以利用epoll_wait函数中的超时参数来进行定时。如果时间堆中无定时器,则超时参数为-1,促使其阻塞,直到有定时器插入事件发生;否则,超时参数等于定时时长。当定时器插入或删除事件发生后,epoll_wait函数返回,随即重新确定定时时长,并修改超时参数,以用于下一次的epoll_wait函数调用。

(3)时间堆框架

 

(4)源代码及注释

#ifndef TIME_HEAP
#define TIME_HEAP

#include <time.h>
#include <vector>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <stdio.h>
#include <pthread.h>

template <typename T> //T是客户类
class th_timer //定时器类
{
public:
    time_t expire; //定时器到期的绝对时刻
    T *user_data; //客户数据,应包含此定时器指针
    void (*cb_func)(T*); //回调函数,即当定时器到期时,要执行的操作
    int loc; //定时器在时间堆中的位置,从堆中删除定时器时会用到
public:
    th_timer(time_t _expire, T *_user, void (*_cb_func)(T*))
    :expire(_expire
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值