一、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");
}
输出结果: