• 用setitimer实现多个定时器


    这篇文章中可以看出,setitimer只能实现一个定时器,如果多次调用setitimer,旧值都会被覆盖掉。

    如何用setitimer实现多个定时器呢?下面是我的一个实现,具体的方法是:

    用链表从小到大维护这些定时器的信息,表头元素的定时器时间最短。当有新的定时器加入时,将它插入到合适的位置;当一个定时时间到达后,更新链表中所有定时器的剩余时间,再次调用setitimer。

    废话不多说,直接上代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <string.h>
    #include <sys/time.h>
    
    typedef struct my_timer_s my_timer_t;
    
    struct my_timer_s {
        my_timer_t *prev, *next;
        int diff_sec;
        int diff_usec;
        void (*func)();
    };
    
    my_timer_t  *timer_list = NULL;
    
    void callback_timeout()
    {
        my_timer_t *p, *q;
        struct itimerval itimer;
        sigset_t set, oldset;
    
        p = timer_list;
    
        sigemptyset(&set);
        sigaddset(&set, SIGALRM);
        sigprocmask(SIG_SETMASK, &set, &oldset);
    
        for (q = timer_list->next; q; q = q->next) {
            q->diff_sec -= p->diff_sec;
            q->diff_usec -= p->diff_usec;
        }
    
        if (timer_list->next != NULL) {
            timer_list = timer_list->next;
    
            itimer.it_interval.tv_sec = 0;
            itimer.it_interval.tv_usec = 0;
            itimer.it_value.tv_sec = timer_list->diff_sec;
            itimer.it_value.tv_usec = timer_list->diff_usec;
    
            setitimer(ITIMER_REAL, &itimer, NULL);
        }
    
        sigprocmask(SIG_SETMASK,&oldset,NULL);
    
        p->func();
    
        free(p);
    }
    
    int register_timer(int sec, int usec, void (*action)())
    {
        my_timer_t  *t, *p, *pre;
        struct itimerval itimer;
        struct sigaction sa;
        sigset_t set, oldset;
    
        t = (my_timer_t *) malloc(sizeof(my_timer_t));
        t->next = t->prev = NULL;
        t->diff_sec = sec;
        t->diff_usec = usec;
        t->func = action;
    
        sigemptyset(&set);
        sigaddset(&set, SIGALRM);
        sigprocmask(SIG_SETMASK,&set,&oldset);
    
        if (timer_list == NULL) {
    
            timer_list = t;
    
        } else {
    
            for (pre = NULL, p = timer_list; p; pre = p, p = p->next) {
                if (p->diff_sec > t->diff_sec ) {
                    t->next = p;
                    p->prev = t;
    
                    if (p->prev) {
                        p->prev->next = t;
                        t->prev = p->prev;
                    }
    
                    break;
                }
            }
    
            if (p == NULL) {
                t->prev = pre;
                pre->next = t;
            }
        }
    
        t = timer_list;
    
        itimer.it_interval.tv_sec = 0;
        itimer.it_interval.tv_usec = 0;
        itimer.it_value.tv_sec = t->diff_sec;
        itimer.it_value.tv_usec = t->diff_usec;
        setitimer(ITIMER_REAL, &itimer, NULL);
    
        sigprocmask(SIG_SETMASK, &oldset, NULL);
    
        return 0;
    }
    
    void func1()
    {
        printf("timer1
    ");
    }
    
    
    void func2()
    {
        printf("timer2
    ");
    }
    
    
    void func3()
    {
        printf("timer3
    ");
    }
    
    
    void timer_handler (int signo)
    {
        switch(signo) {
        case SIGALRM:
            callback_timeout();
            break;
        }
    }
    
    int main ()
    {
        struct sigaction sa;
        struct itimerval itimer;
    
        /*
        memset (&sa, 0, sizeof (sa));
        sa.sa_handler = &timer_handler;
        sa.sa_flags = 0;
        sigemptyset(&sa.sa_mask);
        sigaction(SIGALRM, &sa, NULL);
        */
        signal(SIGALRM, timer_handler);
    
        register_timer(1, 0, &func1);
        register_timer(4, 0, &func2);
        register_timer(5, 0, &func3);
    
        while (1);
    
        return 0;
    }
    

      当然,用堆实现定时器的维护效果会更好。

    未经允许请不要随意转载代码,谢谢。

  • 相关阅读:
    XSLT轻松入门收藏贴
    [网摘学习]使用openstack构建私有云计算平台
    [网摘学习]关于OpenStack架构
    [问题]django_openstack.templatetags
    [网摘学习]5个Linux命令
    关于git使用 命令参考
    [openstack问题]dashboard无法登陆进去的问题
    前台显示后台变量值
    实现浏览器垂直水平居中的 DIV
    IsPostBack作用
  • 原文地址:https://www.cnblogs.com/cobbliu/p/3627448.html
Copyright © 2020-2023  润新知