一、setitimer函数实现
/*mul_timer.h*/
#ifndef _MUL_TIMER_H_
#define _MUL_TIMER_H_
#include
#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
#include
#include
#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
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
#include
#include
#include
#include
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(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
vector 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::iterator iter;
for(iter= pTimer.begin(); iter != pTimer.end(); iter++)
{
(*iter)->StartTimer();
}
return ;
}
int main()
{
SetTimerTask();
sleep(20);
vector::iterator iter;
for(iter= pTimer.begin(); iter != pTimer.end(); iter++)
{
(*iter)->StopTimer();
}
getchar();
return 0;
}
注:个人觉得第二种比较靠谱一点,第一种有时会失效。