最小堆定时器

本文介绍了一个基于最小堆实现的高效定时器系统。该系统利用C语言编程,并结合epoll进行事件监听,能够准确地管理和触发定时任务。通过具体代码展示了如何创建、添加及检查定时器,并提供了一个简单的回调函数示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


#include <sys/epoll.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <inttypes.h>
#include <stdlib.h>
#include "heap.h" // 这个文件是最小堆文件,链接: GO>>

typedef struct mytimer_t
{
    int interval;    // 间隔的时间,毫秒为单位
    uint64_t base;    // 基准的时间
    uint64_t expire;// 超时时候的时间:间隔+基准
    void (*timeout)(struct mytimer_t*);
    int killed;
} mytimer_t;

uint64_t now_time()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);

    uint64_t ret = tv.tv_sec * 1000 + tv.tv_usec / 1000; // 毫秒为单位
    return ret;
}

heap_t timer_heap;

void add_timer(int interval, void(*callback)(mytimer_t*))
{
    mytimer_t* timer = (mytimer_t*)malloc(sizeof(*timer));
    timer->interval = interval;
    timer->timeout = callback;
    timer->base = now_time();
    timer->expire = timer->base + interval;
    timer->killed = 0;

    heap_add(&timer_heap, (void*)timer);
}

void kill_timer(mytimer_t* timer)
{
    timer->killed = 1;
}

int timer_compare(void* node1, void* node2)
{
    mytimer_t* t1 = (mytimer_t*)node1;
    mytimer_t* t2 = (mytimer_t*)node2;

    return t1->expire - t2->expire;
}

int timer_check()
{
    uint64_t now = now_time();

    while (timer_heap.size > 0)
    {
        mytimer_t* t = (mytimer_t*)timer_heap.data[0];

        if (t->expire <= now)        // 超时了的,要在堆里删除
        {
            t->timeout(t);          // 超时调用回调函数
            heap_del(&timer_heap, 0);
        }
        else
        {
            return t->expire - now;    // 还有多长时间超时
        }
    }

    return 70000;                    // 返回一个默认值
}

void callback(mytimer_t* timer)
{
    uint64_t now = now_time();
    printf("callback now = %llu\n", (unsigned long long int)now);
}

int main()
{
    heap_init(&timer_heap, timer_compare);

    int epollfd = epoll_create(1024);
    struct epoll_event ev;

    add_timer(1000, callback);
    add_timer(2000, callback);
    add_timer(5000, callback);

    uint64_t now = now_time();
    printf("now = %llu\n", (unsigned long long int)now);

    while (1)
    {
        int wait_time = timer_check();
        epoll_wait(epollfd, &ev, 1, wait_time); //阻塞等待
    }

    close(epollfd);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值