Linux定时器实现

来源:互联网 发布:php分类信息网源码 编辑:程序博客网 时间:2024/06/04 20:12

Linux定时器实现

在linux中实现定时器功能有多种方法,如sleep,alarm,和signal等,本文主要介绍使用time()和setitimer()函数来实现定时器功能。

使用time()实现定时器

time_t time(time_t *t);

如果t是空指针,直接返回当前时间。如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间。

设计思路:
1.首先获取初始时间
2.判断当前时间与初始时间差是否大于等于定时时间
3.如果满足条件则进行超时处理,并设置前时间为初始时间。
4.循环执行步骤2和3


#include <stdio.h>#include <time.h>#include <pthread.h>time_t last_action;//初始时间或者上一次超时操作的时间int timeout_v=5;//定时周期//读取设置定时周期void* recv_loop(void* data){  while(1){printf("input timeout value:");scanf("%d",&timeout_v);  }}int main(void){pthread_t recv_thread;//创建线程读取随时设置的定时周期if(pthread_create(&recv_thread,0,recv_loop,0)){printf("pthread_creat failed\n");return -1;}time(&last_action);//获取当前时间while(1){//printf("timeout_v:%d\n",timeout_v);if(time(NULL)-last_action>=timeout_v){//判断是否超时printf("******timeout*******\n");//超时处理time(&last_action);//获取当前时间}}}


</pre><pre>
以上程序实现的功能是,开始程序按照默认定时周期执行超时操作,打印******timeout*******。同时该程序还可以随时设置定时周期时间,之后程序便根据新设定的定时周期执行超时操作。

使用setitimer()实现定时器

setitimer()为linux的API,而不是c标准库。该函数有两个功能,一是指定一段时间后执行一个调用函数。二是每间隔一段时间都执行一次调用函数。该函数还有一个特点是,如果上一次定时时间还没有到,再次调用该函数的话,定时器会立即清零。

</pre></blockquote><p><pre name="code" class="objc">int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));  struct itimerval {  struct timeval it_interval;  struct timeval it_value;  };  struct timeval {  long tv_sec;  long tv_usec;  };

其中,which为定时器类型,3中类型定时器如下:  ITIMER_REAL : 以系统真实的时间来计算,它送出SIGALRM信号。    ITIMER_VIRTUAL : -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。    ITIMER_PROF : 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。  第二个参数指定间隔时间,第三个参数用来返回上一次定时器的间隔时间,如果不关心该值可设为NULL。  it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;两者都清零,则会清除定时器。    tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us。   如果是以setitimer提供的定时器来休眠,只需阻塞等待定时器信号就可以了。  setitimer()调用成功返回0,否则返回-1

设计思路:调用setitimer时只设定初始定时时间,在第一次超时之后再调用setitimer设置初始时间。由于setitimer函数超时后会产生相应的信号,那么可以使用signal()处理相应的信号,调用相应的函数,同时再次调用setitimer重新等待超时。

#include <stdio.h>#include <sys/time.h>#include <pthread.h>#include <signal.h>#include <string.h>#include <unistd.h>int time_value=5;//定时周期struct itimervaltimeout_v;//调用定时函数,等到超时void start_up_timer(void){memset(&timeout_v,0,sizeof(struct itimerval));timeout_v.it_value.tv_sec=time_value;timeout_v.it_value.tv_usec=0;//timeout_v.it_interval.tv_sec=time_value;//timeout_v.it_interval.tv_usec=0if(setitimer(ITIMER_REAL,&timeout_v,NULL))printf("set timer failed\n");}//定时周期设置函数,并重启定时函数,清零当前定时时间void* recv_loop(void* data){  while(1){printf("input timeout value:");scanf("%d",&time_value);start_up_timer();  }}//超时调用函数,并重启定时函数。void deal_timeout(int signo){printf("******timeout******\n");start_up_timer();}int main(void){pthread_t recv_thread;signal(SIGALRM,deal_timeout);if(pthread_create(&recv_thread,0,recv_loop,0)){printf("pthread_creat failed\n");return -1;}start_up_timer();while(1){pause();//是进程休眠,等待信号到来}}

以上程序实现的功能是,开始程序按照默认定时周期执行超时操作,打印******timeout*******。同时该程序还可以随时设置定时周期时间并立即清零定时器不管上次定时周期有没有结束,之后程序便根据新设定的定时周期执行超时操作。


0 0