linux下多定時器的實現(經典)__linux

來源:互聯網
上載者:User
一、已有的定時器介面
    時空管理是電腦系統的主要任務。在時間管理中,我們經常利用定時器處理事情:比如tcp協議中利用定時器管理組件逾時,視頻顯示中利用定時器來定時顯示視訊框架,web服務中利用定時器來系統管理使用者的逾時。windows系統提供了SetTimer和timeSetEvent等定時器介面,linux中則提供了setitimer等介面。這些函數的介面很類似,大體上都是使用者提供回呼函數和逾時時間向OS註冊一個定時器事件,OS在逾時時間到了的時候,調用使用者提供的回呼函數來完成使用者想要做的事情。windows下的介面支援單進程中擁有多個定時器,而linux則只允許單進程擁有一個定時器,因此在linux下的單進程中要使用多個定時器,則需要自己維護管理,這是本文寫作的出發點。另外,OS提供的定時器管理演算法在大規模定時器的管理方面可能還不盡人意,這時候就需要使用者去最佳化管理演算法了,本文在這方面提供了一點素材。

二、一個最簡單的多定時器的實現(linux版)
1、實現細節 
  這個實現允許使用者使用多個自訂的定時器,每個自訂的定時器將周期地被觸發直到其被刪除。實現的主要思路是:
    i)首先在初始化多定時器(init_mul_timer)時利用setitimer註冊一個基本的時間單位(如1s)的定時事件;
    ii)使用者需要set_a_timer註冊 自訂定時器 時,在timer_manage管理結構中記錄這個定時器的回呼函數和定時周期等參數;
    iii)當基本的時間單位到期後(如SIGALRM訊號到達時),遍曆整個timer_manage,如果有自訂定時器的逾時時間到了,就執行相應的回呼函數,並將 自訂定時器 的逾時時間置為最初值;否則將 自訂定時器 的逾時時間相應地減一個基本的時間單位;
    iv)使用者通過del_a_timer來刪除某個定時器,通 過destroy_mul_timer來刪除整個多定時器。
2、代碼
i) mul_timer.h

/* This file provides an interface of multiple timers. for convenience, it simplify signal processing.
 * Also, it can't be used in multithreading environment.
 * Author:bripengandre
 * Date:2009-04-29
 */
#ifndef _MUL_TIMER_H_
#define _MUL_TIMER_H_

#include <sys/time.h>

#define MAX_TIMER_CNT 10
#define MUL_TIMER_RESET_SEC 10
#define TIMER_UNIT 60
#define MAX_FUNC_ARG_LEN 100
#define INVALID_TIMER_HANDLE (-1)

typedef int timer_handle_t;

typedef struct _timer_manage
{
    struct _timer_info
    {
        int state; /* on or off */
        int interval;
        int elapse; /* 0~interval */
        int (* timer_proc) (void *arg, int arg_len);
        char func_arg[MAX_FUNC_ARG_LEN];
        int arg_len;
    }timer_info[MAX_TIMER_CNT];

    void (* old_sigfunc)(int);
    void (* new_sigfunc)(int);
    struct itimerval value, ovalue;
}_timer_manage_t;

/* success, return 0; failed, return -1 */
int init_mul_timer(void);
/* success, return 0; failed, return -1 */
int destroy_mul_timer(void);
/* success, return timer handle(>=0); failed, return -1 */
timer_handle_t set_a_timer(int interval, int (* timer_proc) (void *arg, int arg_len), void*arg, int arg_len);
/* success, return 0; failed, return -1 */
int del_a_timer(timer_handle_t handle);

#endif /* _MUL_TIMER_H_ */

ii)mul_timer.c

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <time.h> 
#include "mul_timer.h"

static struct _timer_manage timer_manage;

static void sig_func(int signo);

/* success, return 0; failed, return -1 */
int init_mul_timer(void)
{
    int ret;
    
    memset(&timer_manage, 0, sizeof(struct _timer_manage));
    if( (timer_manage.old_sigfunc = signal(SIGALRM, sig_func)) == SIG_ERR)
    {
        return (-1);
    }
    timer_manage.new_sigfunc = sig_func;
    
    timer_manage.value.it_value.tv_sec = MUL_TIMER_RESET_SEC;
    timer_manage.value.it_value.tv_usec = 0;
    timer_manage.value.it_interval.tv_sec = TIMER_UNIT;
    timer_manage.value.it_interval.tv_usec = 0;
    ret = setitimer(ITIMER_REAL, &timer_manage.value, &timer_manage.ovalue); 
    
    return (ret);
}


/* success, return 0; failed, return -1 */
int destroy_mul_timer(void)
{
    int ret;
    
    if( (signal(SIGALRM, timer_manage.old_sigfunc)) == SIG_ERR)
    {
        return (-1);


    }

    ret = setitimer(ITIMER_REAL, &timer_manage.ovalue, &timer_manage.value);
    if(ret < 0)
    {
        return (-1);
    } 
    memset(&timer_manage, 0, sizeof(struct _timer_manage));
    
    return(0);
}


/* success, return timer handle(>=0); failed, return -1 */
timer_handle_t set_a_timer(int interval, int (* timer_proc) (void *arg, int arg_len), void *arg,int arg_len)
{
    int i;
    
    if(timer_proc == NULL || interval <= 0)
    {
        return (-1);
    } 
    
    for(i = 0; i < MAX_TIMER_CNT; i++)
    {
        if(timer_manage.timer_info[i].state == 1)
        {
            continue;
        }
        
        memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));
        timer_manage.timer_info[i].timer_proc = timer_proc;
        if(arg != NULL)
        {
            if(arg_len > MAX_FUNC_ARG_LEN)
            {
                return (-1);
            }
            memcpy(timer_manage.timer_info[i].func_arg, arg, arg_len);
            timer_manage.timer_info[i].arg_len = arg_len;
        }
        timer_manage.timer_info[i].interval = interval;
        timer_manage.timer_info[i].elapse = 0;
        timer_manage.timer_info[i].state = 1;
        break;
    }
    
    if(i >= MAX_TIMER_CNT)
    {
        return (-1);
    }
    return (i);
}


/* success, return 0; failed, return -1 */
int del_a_timer(timer_handle_t handle)
{
    if(handle < 0 || handle >= MAX_TIMER_CNT)
    {
        return (-1);
    }
    
    memset(&timer_manage.timer_info[handle], 0, sizeof(timer_manage.timer_info[handle]));
    
    return (0);
}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.