一、Windows下的定时器函数
当程序种需要每隔一段时间执行一件事的时候,就需要使用SetTimer函数了。使用定时器的方法比较简单,通常定义一个时间间隔,然后WINDOWS以此时间间隔周期性的触发程序。通常有两种方法来实现:
1〉 发送WM_TIMER消息。
2〉 调用应用程序定义的回调函数
1、 SetTimer函数
1> API函数SetTimer的原型
UINT_PTRSetTimer( HWND hWnd, // 窗口句柄 UINT_PTR nIDEvent, // 定时器ID,多个定时器时,可以通过该ID判断是哪//个定时器 UINT uElapse, // 时间间隔,单位为毫秒 TIMERPROC lpTimerFunc // 回调函数 );
例如 :
SetTimer(m_hWnd,1,1000,NULL); //窗口m_hWnd中一个ID为1的1秒触发一次的定时器
2> MFC程序中的SetTimer
在MFC程序中SetTimer被封装在CWnd类中。调用就不用指定窗口句柄了。于是SetTimer函数的原型变为:
UINT SetTimer( UINT nIDEvent, // 定时器ID,多个定时器时,可以通过该ID判断是哪/个定时器 UINT nElapse, // 时间间隔,单位为毫秒 void(CALLBACKEXPORT *lpfnTimer)(HWND,UINT ,YINT ,DWORD) // 回调函数 );
例:
SetTimer(1,1000,NULL);//一个ID为1的1秒触发一次的定时器
2、 回调函数
1〉 发送WM_TIMER消息,SetTimer(1,1000,NULL);
SetTimer的第三个参数是一个回调函数,在这个函数里,放入你想要做的事情的代码,将它设定为NULL,也就是使用系统默认的回调函数onTime函数。在需要计时器的类的生成onTime函数的方法:
在ClassWizard里,选择需要计时 器的类,添加WM_TIME消息映射,就自动生成onTime函数了。
然后在函数里添加代码,让代码实现功能。每隔一段时间就会自动执行一次。
2〉 调用应用程序定义的回调函数
首先定义一个回调函数:
void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINTnTimerid,DWORD dwTime);
然后再用SetTimer(1,100,TimerProc)函数来建一个定时器,第三个参数就是回调函数地址。
3、 多个定时器
当程序中需要在不同的时刻执行不同的事件的时候,就需要定义多个定时器。通过定时ID来区分。
SetTimer(2,1000,NULL);
SetTimer(3,500,NULL);
此时onTimer函数体也要发生变化,要在函数体内添加每一个timer的处理代码:
onTimer(nIDEvent) { switch(nIDEvent) { case 1:........; break; case 2:.......; break; case 3:......; break; } }
二、Linux下的定时器函数
1. Alarm
1〉 alarm函数
函数原型:
unsigned int alarm(unsigned int seconds);
头文件:
#include<unistd.h>
作用:
alarm函数,用来定时,当到达定时的时间后,内核会发送SIGALRM信号给进程,默认会结束进程。当然,也可以通过signal函数为信号SIGALRM设置处理函数。
如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。
返回值:如果调用此alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。 出错返回-1。
2〉例子
例一:使用默认信号处理函数,接收到SIGALRM后结束进程
#include <stdio.h> #include <unistd.h> #include <signal.h> int main(int argc,char *argv[]) { alarm(3); int i =0; for(i=0;i<3;i++) { printf("%d\n",i); sleep(1); } printf("end"); return0; }
输出结果:
0
1
2
alarm signal
例二:通过signal函数指定处理函数
#include <stdio.h> #include <unistd.h> #include <signal.h> unsigned a; void fun(int sig); int main(int argc,char *argv[]) { alarm(3); signal(SIGALRM,fun); inti=0; for(i=0;i<3;i++) { printf("%d\n",i); sleep(1); } printf("end\n"); return0; } void fun(int sig) { if(sig== SIGALRM) printf("gettimer alarm!\n"); else printf("gettimer failed!\n"); }
运行结果:
例三:查看不同情况下alarm 的返回值
#include <stdio.h> #include <unistd.h> #include <signal.h> unsigned a; void fun(int sig); int main(int argc,char *argv[]) { unsignedint a,b; alarm(10); sleep(5); a=alarm(0); printf("Therest time of the first alarm is %u\n",a); b=alarm(3); signal(SIGALRM,fun); inti=0; for(i=0;i<3;i++) { printf("%d\n",i); sleep(1); } printf("Thereturn valuable of the last alarm is %u\nend\n",b); return0; } void fun(int sig) { if(sig== SIGALRM) printf("gettimer alarm!\n"); else printf("gettimer failed!\n"); }
输出结果:
2. setitimer
setitimer()为Linux的API,与C语言的StandardLibrary中的SetTimer不同。setitimer()有两个功能,
一是指定一段时间后,才执行某个function,类似alarm,但是精度高。
二是每间格一段时间就执行某个function,与windows下SetTimer 功能类似
以下程序demo如何使用setitimer()
1> setitimer函数
函数原型:
int setitimer( int which, const structitimerval *restrict value, struct itimerval*restrict ovalue );
头文件:
#include <sys/time.h>
参数分析:
a. which: 指定定时器类型
setitimer支持3种类型的定时器:
ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。
ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
b. value: 结构itimerval的一个实例,用来设定定时时间。
结构体itimerval和timeval定义如下:
structitimerval { struct timerval it_interval; //指定间隔时间 struct timerval it_value; //指定初始定时时间 }
itimerval.it_value设定第一次执行function所延迟的秒数, itimerval.it_interval设定以后每几秒执行function。
所以若只想延迟一段时间执行function,只要设定 itimerval.it_value即可。
若要设定间格一段时间就执行function,则it_value和it_interval都要设定,否则 funtion的第一次无法执行,就别说以后的间隔执行了。
两者都清零,则会清除定时器。
tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us。
struct timeval { long tv_sec; long tv_usec; }
c. ovalue: 用来保存先前的值,可不做处理,通常为NULL。
返回值:setitimer()调用成功返回0,否则返回-1。
2> 例子
例一:
#include <stdio.h> #include <unistd.h> #include <signal.h> #include <sys/time.h> #include <string.h> void printMsg(int sig); int main(int argc,char *argv[]) { int res= 0; signal(SIGALRM,printMsg); structitimerval tick; memset(&tick,0,sizeof(tick)); tick.it_value.tv_sec= 3; tick.it_value.tv_usec= 0; tick.it_interval.tv_sec= 1; tick.it_interval.tv_usec= 0; res =setitimer(ITIMER_REAL,&tick,NULL); if(res) { printf("Settimer failed!!\n"); } int i =0; for(i=0;i<10;i++) { printf("%d\n",i); sleep(1); } printf("Theend!\n"); return0; } void printMsg(int sig) { if(sig== SIGALRM) printf("gettimer alarm!\n"); else printf("gettimer failed!\n"); }
输出结果 :
例二:
#include <stdio.h> #include <unistd.h> #include <signal.h> #include <sys/time.h> #include <string.h> void printMsg(int sig); int main(int argc,char *argv[]) { int res= 0; signal(SIGALRM,printMsg); structitimerval tick; memset(&tick,0,sizeof(tick)); tick.it_value.tv_sec= 3; tick.it_value.tv_usec= 4000000; tick.it_interval.tv_sec= 1; tick.it_interval.tv_usec= 0; res =setitimer(ITIMER_REAL,&tick,NULL); if(res) { printf("Settimer failed!!\n"); } int i =0; for(i=0;i<10;i++) { printf("%d\n",i); sleep(1); } printf("Theend!\n"); return0; } void printMsg(int sig) { if(sig== SIGALRM) printf("gettimer alarm!\n"); else printf("gettimer failed!\n"); }
输出结果:
例三:
#include <stdio.h> #include <unistd.h> #include <signal.h> #include <sys/time.h> #include <string.h> void printMsg(int sig); int main(int argc,char *argv[]) { int res= 0; signal(SIGALRM,printMsg); structitimerval tick,old_tick; memset(&tick,0,sizeof(tick)); memset(&tick,0,sizeof(old_tick)); tick.it_value.tv_sec= 3; tick.it_value.tv_usec= 0; tick.it_interval.tv_sec= 1; tick.it_interval.tv_usec= 0; res =setitimer(ITIMER_REAL,&tick,&old_tick); if(res) { printf("Settimer failed!!\n"); } int i =0; for(i=0;i<10;i++) { printf("%d\n",i); printf("value.sec= %ld ,value.usec = %ld \ninterval.sec = %ld ,interval.usec = %ld\n",old_tick.it_value.tv_sec,old_tick.it_value.tv_usec,old_tick.it_interval.tv_sec,old_tick.it_interval.tv_usec); sleep(1); } printf("Theend!\n"); return0; } void printMsg(int sig) { if(sig== SIGALRM) printf("gettimer alarm!\n"); else printf("gettimer failed!\n"); }
输出结果: