简单定时器

本文基于循环数组实现了一个简单的时间轮定时器。

定时器可以出发单次或者循环触发。定时器,每隔一秒往下走一个格子,并扫描数组节点中有无要触发的事件。一个格子中可能有多个节点,触发层级为0的节点。这个例子比较简单,通过alarm系统调用来实现的,alarm会发SIGALRM信号,触发tick函数执行。

 

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

#define TIME_WHEEL_SIZE 8          // 轮子大小
typedef void (*func_t)(int data);  // 回调函数类型

// 时间轮节点
struct timer_node {
    int rotation;             //轮数,有多少轮
    func_t func;              // 回调函数
    int data;                 // 回调函数的参数
    struct timer_node *next;  // 下一个节点
};

// 时间轮
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];  //当前slot
    while (*cur) {
        struct timer_node *curr = *cur;
        if (curr->rotation > 0) {
            curr->rotation--;
            cur = &curr->next;
        } else {
            curr->func(curr->data);
            *cur = curr->next;
            free(curr);
        }
    }
    timer.current = (timer.current + 1) % TIME_WHEEL_SIZE;
    alarm(1);  // 如果要多次触发,通常的做法是在这行加入alarm
}

// 添加节点
void add_timer(int len, func_t func) {
    int pos = (len + timer.current) % TIME_WHEEL_SIZE;  // 新增节点的位置
    struct timer_node *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->func = func;
}
int g_sec = 0;

void do_time1(int data) {
    printf("timer %s, %d\n", __FUNCTION__, g_sec++);
    add_timer(1, do_time1);  // 循环添加
}

// 只打印一次
void do_time2(int data) { printf("timer %s, %d\n", __FUNCTION__, g_sec++); }

int main(int argc, char const *argv[]) {
    signal(SIGALRM, tick);
    alarm(1);
    add_timer(1, do_time1);
    add_timer(3, do_time2);
    add_timer(15, do_time2);
    // alarm(1);// signal只生效一次,之后恢复默认,多次调用alarm不会回调
    while (1) pause();
    return 0;
}

 

 

参考:

[1]Linux C/C++定时器的实现原理和使用方法

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值