Linux定时器分析-源码sample

1 篇文章 0 订阅
1 篇文章 0 订阅
/*
 * time_test.c
 *
 *  Created on: 2015年6月3日
 *      Author: gcooq
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/queue.h>


#define MAX_TIMER_NUM 1000
#define TIMER_START 1
#define TIMER_TICK 1   //一个tick滴答
#define INVALID_TIMER_ID  (-1)  //无效ID
#ifndef TRUE
#define TRUE 1
#endif


#ifndef FALSE
#define FALSE 0
#endif


typedef int  timer_id;  //计时器的ID


//当一个timer时间满时调用timer_expiry()函数
typedef int timer_expiry(timer_id id,void *user_data,int len);


/*timer结构定义*/


struct timer{
LIST_ENTRY(timer)  entries; //list  entry
timer_id id; //timer的ID
int  interval;                                         //timer间隔
int elapse;                                          //timer
timer_expiry *cb;               //如果时间满则调用
void *user_data;             //回调参数
int len;                               //user_data 长度
};


//timer list
struct timer_list{
LIST_HEAD(listheader,timer)  header;    //list header
int num;                                                    //计时器实体数目
int max_num;                                           //最大的实体数目
void  (*old_sigfunc)(int);                //保存之前的信号句柄Handler
void (*new_sigfunc)(int);            //信号句柄
struct itimerval ovalue;                  //旧的时间值
struct itimerval value;                 //our internal timer value
};




//函数操作


int  init_timer(int count);
int destroy_timer(void);
timer_id add_timer(int interval,timer_expiry *cb,void *user_data,int len);


int del_timer(timer_id id);


static struct timer_list timer_list;
static void sig_func(int signo);


//创建一个计时器
//返回值返回0表示成功
int init_timer(int count){
    int ret=0;
    if(count<=0||count>MAX_TIMER_NUM){
    printf("计时器最大数量为%d.\n",MAX_TIMER_NUM);
    return -1;//失败
    }


    memset(&timer_list,0,sizeof(struct timer_list));//分配内存


    LIST_INIT(&timer_list.header);
    timer_list.max_num=count;  //构造队列
    //注册内部信号句柄并且存储旧的信号句柄
    if((timer_list.old_sigfunc=signal(SIGALRM,sig_func))==SIG_ERR){
    return -1;


    }
    timer_list.new_sigfunc=sig_func;


    //设置内部计时器驱动多计时器和村粗就得计时器值
    timer_list.value.it_value.tv_sec=TIMER_START;
    timer_list.value.it_value.tv_usec=0;
    timer_list.value.it_interval.tv_sec=TIMER_TICK;
    timer_list.value.it_interval.tv_usec=0;
    ret=setitimer(ITIMER_REAL,&timer_list.value,&timer_list.ovalue);
    return ret;
}


//删除timerlist
int destroy_timer(void){
struct timer *node=NULL;
if((signal(SIGALRM,timer_list.old_sigfunc))==SIG_ERR){
return -1;
}
if((setitimer(ITIMER_REAL,&timer_list.ovalue,&timer_list.value))<0){
return -1;


}
while(!LIST_EMPTY(&timer_list.header)){ ///直到队列为空
node=LIST_FIRST(&timer_list.header);
LIST_REMOVE(node,entries);
//释放node
printf("移除 id %d\n",node->id);
free(node->user_data);
free(node);
}
memset(&timer_list,0,sizeof(struct timer_list));
return 0;
}
//增加计时器到计时器列表中
/*
 * cb cb!=NULL&&timer expiry,调用
 * 返回值为计时器ID  if==INVALID_TIMER ,添加失败
 * */
timer_id add_timer(int interval,timer_expiry *cb,void *user_data,int len){


struct timer *node=NULL;
if(cb==NULL||interval<=0){
return INVALID_TIMER_ID;
}
if(timer_list.num<timer_list.max_num){
timer_list.num++;
}
else{
return INVALID_TIMER_ID;//list加满了


}
if((node=malloc(sizeof(struct timer)))==NULL){
return INVALID_TIMER_ID;
}
if(user_data!=NULL||len!=0){
node->user_data=malloc(len);
memcpy(node->user_data,user_data,len);
node->len=len;
}
node->cb=cb;
node->interval=interval;
node->elapse=0;
node->id=timer_list.num;
LIST_INSERT_HEAD(&timer_list.header,node,entries);
return node->id;
}


//Delete  a timer from time list
int del_timer(timer_id id){


if(id<0||id>timer_list.max_num){
return -1;
}
struct timer *node=timer_list.header.lh_first;
for(;node!=NULL;node=node->entries.le_next){
printf("Total timer num 是 %d /timer id %d.\n",timer_list.num,id);
if(id==node->id){
LIST_REMOVE(node,entries);
timer_list.num--;
free(node->user_data);
free(node);
return 0;
}
}


//找不到计时器
return -1;
}
/*Tick Bookkeeping*/
static void sig_func(int signo){
struct timer *node=timer_list.header.lh_first;
for(;node!=NULL;node=node->entries.le_next){
node->elapse++;
if(node->elapse>=node->interval){ //说明tick大于允许的间隔时间大于或者等于的话将执行cb回调函数
node->elapse=0;
node->cb(node->id,node->user_data,node->len);
}
}
}
static char *fmt_time(char *tstr){
//格式化时间
time_t t;
t=time(NULL);
strcpy(tstr,ctime(&t));
tstr[strlen(tstr)-1]='\0';//结束字符
return tstr;
}
//单元测试
timer_id  id[3];
timer_id call_cnt=0;
int timer1_cb(timer_id id,void *arg,int len){
char tstr[200];
static int i,ret;


printf("欢迎 [%s] /id %d:timer1_cb is here.\n",fmt_time(tstr),id);
if(i>10){
ret=del_timer(id);
printf("timer1_cb:%s del_timer/id %d::ret=%d\n",fmt_time(tstr),id,ret);
}
i++;
call_cnt++;
return 0;
}
int timer2_cb(timer_id id,void *arg,int len){
char tstr[200];
static int i,ret;


printf("欢迎 [%s] /id %d:timer2_cb is here.\n",fmt_time(tstr),id);
if(i>10){
ret=del_timer(id);
printf("timer2_cb:%s del_timer/id %d::ret=%d\n",fmt_time(tstr),id,ret);
}
i++;
call_cnt++;
return 0;
}
int timer3_cb(timer_id id,void *arg,int len){
char tstr[200];
static int i,ret;
printf("欢迎 [%s] /id %d:timer3_cb is here.\n",fmt_time(tstr),id);
if(i>10){
ret=del_timer(id);
printf("timer1_cb:%s del_timer/id %d::ret=%d\n",fmt_time(tstr),id,ret);
}
i++;
call_cnt++;
return 0;


}
int main(void ){  //主函数
char arg[50];
char args[100];
char tstr[200];
int ret;
struct timespec time;
time.tv_sec=0;  //秒
time.tv_nsec=100000000;  //微毫秒


init_timer(MAX_TIMER_NUM);//初始化


id[0]=add_timer(1,timer1_cb,NULL,0);
printf("注册timer id[0]=%d\n",id[0]);


id[1]=add_timer(2,timer2_cb,arg,50);
printf("注册timer id[1]=%d\n",id[1]);


id[2]=add_timer(3,timer3_cb,args,100);
printf("注册timer id[2]=%d\n",id[2]);
while(1){
if(call_cnt>10){
break;
}
nanosleep(&time,NULL);
}
ret=destroy_timer();
printf("mainL%s destroy_timer,ret=%d\n",fmt_time(tstr),ret);
return 0;


}













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值