最小堆定时器

来源:互联网 发布:汽车编程 编辑:程序博客网 时间:2024/04/28 16:09

#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);
}
0 0
原创粉丝点击