linux定时器的实现

一、setitimer函数实现

<pre class="cpp" name="code">/*mul_timer.h*/
#ifndef _MUL_TIMER_H_
#define _MUL_TIMER_H_

#include <sys/time.h>

#define MAX_TIMER_CNT 10
#define MUL_TIMER_RESET_SEC 1
#define TIMER_UNIT 1
#define MAX_FUNC_ARG_LEN 100
#define INVALID_TIMER_HANDLE (-1)
#define BASE_TIMER (10*1000) //10ms

typedef int timer_handle_t;
extern timer_handle_t hd[MAX_TIMER_CNT];

typedef struct _timer_info
{
    int state; /* on or off */
    int interval; //ms
    int elapse;
    int (* timer_proc) (void *arg, int arg_len);
    char func_arg[MAX_FUNC_ARG_LEN];
    int arg_len;
} TimerInfo;

typedef struct _timer_manage
{
    TimerInfo 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_ */

/*mul_timer.cpp*/
#include <string.h>
#include <signal.h>
#include <time.h>
#include "mul_timer.h"

static struct _timer_manage timer_manage;
timer_handle_t hd[MAX_TIMER_CNT] = {-1};

static void sig_func(int signo);

int init_mul_timer(void)
{
    int ret = -1;

    memset(&timer_manage, 0, sizeof(struct _timer_manage));
    if( (timer_manage.old_sigfunc = signal(SIGALRM, sig_func)) == SIG_ERR)
    {
        return ret;
    }
    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 = 0;
    timer_manage.value.it_interval.tv_usec = BASE_TIMER;
    ret = setitimer(ITIMER_REAL, &timer_manage.value, &timer_manage.ovalue);

    return (ret);
}

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);
}

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);
}

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);
}


static void sig_func(int signo)
{
    int i;
    for(i = 0; i < MAX_TIMER_CNT; i++)
    {
        if(timer_manage.timer_info[i].state == 0)
        {
            continue;
        }
        timer_manage.timer_info[i].elapse += BASE_TIMER/1000; //ms
        if(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)
        {
            timer_manage.timer_info[i].elapse = 0;
            timer_manage.timer_info[i].timer_proc(timer_manage.timer_info[i].func_arg, timer_manage.timer_info[i].arg_len);
        }
    }
}
#include "mul_timer.h"
#include <cstdio>

int fun1(void *arg, int len)
{
    printf("This is fun1\n");
    return 0;
}

int fun2(void *arg, int len)
{
    printf("This is fun2\n");
    return 0;
}

int fun3(void *arg, int len)
{
    printf("This is fun3\n");
    return 0;
}

void SetTimerTask()
{
    printf("set timer task\n");
    static int i = 0;
    
    int ret = init_mul_timer();
    if (ret != 0)
    {
        printf("set timer failed.\n");
    }else
    {
        hd[i] = set_a_timer(2*1000, fun1, NULL, 0);//2 seconds
        i++;
        hd[i] = set_a_timer(5*1000, fun2, NULL, 0); //5 seconds
        i++;
        hd[i] = set_a_timer(1*1000, fun3, NULL, 0); // 1 second
    }

    return ;
}

int main()
{
    SetTimerTask();

    getchar();
    return 0;
}




 

二、select+thread实现

#ifndef CTIMER_H_
#define CTIMER_H_

#include <pthread.h>
#include <sys/time.h>
#include <cstring>
#include <sys/select.h>
#include <time.h>


class CTimer
{
private:
    pthread_t thread_timer;
    int (*timer_proc)(void *arg, int arg_len);
    char *func_arg;
    int arg_len;
    long m_second, m_microsecond;
    static void *OnTimer_stub(void *p)
    {
        (static_cast<CTimer*>(p))->thread_proc();
        return (void*)0;
    }
    void thread_proc();
    void OnTimer();
    CTimer();
public:
    CTimer(long second, long microsecond,
           int (*timer_proc_callback)(void *arg, int arg_len),
           void *arg = NULL, int arg_length = 0);
    virtual ~CTimer();
    void ModifyTimer(long second,long microsecond);
    void StartTimer();
    void StopTimer();
};


#endif


 

#include "CTimer.h"

CTimer::CTimer()
{
    
}

CTimer::CTimer(long second, long microsecond,
               int (*timer_proc_callback)(void *arg, int arg_len),
               void *arg, int arg_length)
{
    m_second = second;
    m_microsecond = microsecond;
    timer_proc = timer_proc_callback;
    arg_len = arg_length;
    func_arg = NULL;
    if (arg != NULL)
    {
        func_arg = new char[arg_length];
        memcpy(func_arg, arg, arg_length);
    }
}

CTimer::~CTimer()
{
    if (func_arg != NULL)
    {
        delete[] func_arg;
        func_arg = NULL;
    }
}

void CTimer::ModifyTimer(long second, long microsecond)
{
    m_second = second;
    m_microsecond = microsecond;
    return ;
}

void CTimer::StartTimer()
{
    pthread_create(&thread_timer, NULL, OnTimer_stub, this);
    return ;
}

void CTimer::StopTimer()
{
    pthread_cancel(thread_timer);
    pthread_join(thread_timer, NULL);
    return ;
}

void CTimer::thread_proc()
{
    while (true)
    {
        OnTimer();
        pthread_testcancel();
        struct timeval tempval;
        tempval.tv_sec = m_second;
        tempval.tv_usec = m_microsecond;
        select(0, NULL, NULL, NULL, &tempval);
    }
    return ;
}

void CTimer::OnTimer()
{
    timer_proc(func_arg, arg_len);
    return ;
}


 

#include "CTimer.h"
#include <cstdio>

vector<CTimer*> pTimer;

int fun1(void *arg, int len)
{
    printf("This is fun1\n");
    return 0;
}

int fun2(void *arg, int len)
{
    printf("This is fun2\n");
    return 0;
}

int fun3(void *arg, int len)
{
    printf("This is fun3\n");
    return 0;
}

void SetTimerTask()
{
    printf("set timer task\n");
    CTimer* temp = new CTimer(2, 0, fun1);
    pTimer.push_back(temp);
    temp = new CTimer(5, 0, fun2);
    pTimer.push_back(temp);
    temp = new CTimer(1, 0, fun3);
    pTimer.push_back(temp);

    vector<CTimer*>::iterator iter;
    for(iter= pTimer.begin(); iter != pTimer.end(); iter++)
    {
        (*iter)->StartTimer();
    }   
    
    return ;
}

int main()
{
    SetTimerTask();
    sleep(20);
    
    vector<CTimer*>::iterator iter;
    for(iter= pTimer.begin(); iter != pTimer.end(); iter++)
    {
        (*iter)->StopTimer();
    }
    
    getchar();
    return 0;
}


个人觉得第二种比较靠谱一点,第一种有时会失效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值