数据结构之时间轮Timeingwheel以及timer实现

本文介绍了如何利用时间轮数据结构实现一个简单的定时器。通过循环数组和链表,将不同延迟时间的任务映射到相应的位置,当时间轮转动到对应位置时,执行已到达时间的任务。代码示例中展示了添加定时器、处理超时任务的逻辑,并在main函数中运行了两个不同间隔的定时器。
摘要由CSDN通过智能技术生成

所谓时间轮就是一个循环数组,每过一个时钟周期,数组下标前进一格。每个数组的entry后面挂着一个list, 有点类似于哈希链表。哈希表链表node是因为散列冲突, 时间轮链表node是因为对数组size取模有相同的余数。比如有6个node: 1, 4,7, 10, 13, 16 。数组size = 6,  那么时间轮里的数据如下图所示

因为:

1,7,13对6做%运算结果都相同

4,10, 16对6做%运算结果都相同

那么怎么用时间轮去实现一个timer呢,算法如下:

list node 存储一个关键信息rotation(代表时间轮要走几轮), rotation = timer % 数组size. 以上为例,有 1, 4 , 7 , 10, 13 , 16 这6个timer, 那么:

timer 1 , rolation = 1 /6 = 0

timer 4,  rolation = 4 / 6 = 0

timer 7, rolation = 7 / 6 = 1

...

timer 16, rolation = 16 / 6 = 2.

当时间轮走到某个数组元素时,遍历该数组元素之后的list. 对于每个list node , 如果其rotation = 0, 则说明时间

到了, 执行其callback 然后删除该node. 否则rotation--.

具体代码:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

#define TIME_WHEEL_SIZE 6 

typedef void (*func)(int data);
struct timer_node 
{
   struct timer_node *next;
   int rotation;
   func proc;       //timeout callback
   int data;
};

struct timer_wheel 
{
    struct timer_node *slot[TIME_WHEEL_SIZE];
    int current;
};

struct timer_wheel timer = {{0}, 0};
void tick(int signo)
{
    struct timer_node **cur = &timer.slot[timer.current];
    while (*cur) 
    {
        struct timer_node *curr = *cur;
        if (curr->rotation > 0)     //time do not out, wait until the next round
        {
             curr->rotation--;
             cur = &curr->next;
        } 
        else                       //timeout, execute callback, and delete timer node
        {
             curr->proc(curr->data);
             *cur = curr->next;
             free(curr);
        }
    }
    
    timer.current = (timer.current + 1) % TIME_WHEEL_SIZE;
    alarm(1);                     // trigger the alarm signal in 1s 
}

void add_timer(int len, func action)
{
    int pos = (len + timer.current) % TIME_WHEEL_SIZE;
    struct timer_node *node = (timer_node *)malloc(sizeof(struct timer_node));
    node->next = timer.slot[pos];
    timer.slot[pos] = node;
    node->rotation = len / TIME_WHEEL_SIZE;
    node->data = 0;
    node->proc = action;
}

int g_sec1 = 0;
void do_time1(int data)          //timer callback
{
    printf("%s timer %d\n", __FUNCTION__, g_sec1++);
    add_timer(1, do_time1);      //add the timer again
}

void do_time9(int data)
{
    printf("%s timer %d\n", __FUNCTION__, g_sec1);
    add_timer(9, do_time9);      
}

int main()
{

 signal(SIGALRM, tick);
 alarm(1); 
 add_timer(1, do_time1);
 add_timer(9, do_time9);
 while(1) pause();

 return 0;
}

 result:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一条叫做nemo的鱼

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值