高性能定时器-------时间轮

          基于排序链表的定时器(https://blog.csdn.net/destory27/article/details/81748580)存在一个问题:添加定时器的效率偏低。

         如图所示时间轮内,指针指向轮子上的一个槽,它以恒定的速度顺时针旋转,每旋转一步就指向先一个槽.该时间轮共有N个槽,旋转一周的时间是N*Si,每个槽指向一条定时器链表,没条链表上的定时器具有相同的特征:它们的定时时间相差N*Si的整数倍.时间轮正是利用这个关系将定时器散列到不同的链表中。假如现在指针指向槽cs,我们要添加一个定时时间为ti的定时器,则该定时器将被插入槽ts对应的链表:     ts = (cs + ti / si) % N.

        基于排序链表的定时器使用唯一的一条链表来管理所有的定时器,所有插入操作的效率随着定时器数目的增多而降低.而时间轮使用哈希表思想,将定时器散列到不同的链表上.对于时间轮,要提高定时精度,就要使si值足够小;要提高执行效率,则要求N值足够大.

#ifndef _TIME_WHEEL_TIMER
#define _TIME_WHEEL_TIMER
//时间轮
#include <time.h>
#include <netinet/in.h>
#include <iostream>

#define BUFFER_SIZE  64

class tw_timer;  //前向声明

//绑定socket和定时器
struct client_data{
    struct sockaddr_in address;  //addr
    int sockfd;                
    char buf[BUFFER_SIZE];
    tw_timer *timer;
};

/********定时器类*********/
class tw_timer{
    public:
        tw_timer(int rot, int ts)
            :rotation(rot),
             time_slot(ts)
        {}
        
        void (*cb_func)(client_data *);  //定时器回调函数

    public:
        int rotation; //时间轮转多少圈后生效
        int time_slot;     //属于时间轮上哪个槽
        client_data *user_data{nullptr};   //客户数据
        tw_timer *next{nullptr};   //指向下一个定时器
        tw_timer *prev{nullptr};   //指向前一个定时器

};

class time_wheel{
    public:
        time_wheel();
        ~time_wheel();

        tw_timer *add_timer(int timeout);   //根据定时值timeout创建一个定时器 插入合适的槽中
        void del_timer(tw_timer *timer);    //删除目标定时器timer
        void tick();                       //SI时间到后,调用该函数 时间轮前滚动一个槽的间隔

    private:
        static const int N = 60;  //时间轮上槽的数目
        static const int SI = 1; //槽间隔1S
        tw_timer *slots[N];    //槽
        int cur_slot{0}; //当前槽
};

time_wheel::time_wheel()
{
    for(int i = 0; i < N; ++i)
        slots[i] = nullptr;
}

time_wheel::~time_wheel()
{
    for(int i = 0; i < N; ++i)
    {
        tw_timer *tmp = slots[i];
        while(tmp)
        {
            slots[i] = tmp->next;
            delete tmp;
            tmp = slots[i];
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值