在linux下实现精度较高的定时功能,需要用到setitimer 和 getitimer函数。
函数原型:
#include <sys/time.h>
int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
· 函数getitimer()把指定的定时器类型( ITIMER_REAL, ITIMER_VIRTUAL, 或 ITIMER_PROF中的一个)写入curr_value指向的结构。
it_value设置为定时器剩余时间(若定时器关闭则为0)。类似的,it_interval设置为复位时间。
分析形参:
1. int which
struct itimerval
{
struct timeval it_interval;//next value
struct timeval it_value;//current value
};
timeval也是一个数据类型:
struct timeval
{
long tv_sec;
long tv_usec;
};
it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;两者都清零,则会清除定时器。tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先。
3. struct itimerval *ovalue
ovalue用来保存先前的值,通常设置为NULL。
每次定时循环结束会产生中断,通常会用到signal函数捕捉处理,原型为:
#include<signal.h>
void (* signal(int sig, void (*func) (int)) ) (int);
signal()是一个系统调用,常用来设定某个信号(sig)的处理方法(func):
信号类型(sig)
(1) 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。
(2) 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。
(3) 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。
(4) 与执行系统调用时遇到非预测错误条件相关的信号。如执行一个并不存在的系统调用。
(5) 在用户态下的进程发出的信号。如进程调用系统调用kill向其他进程发送信号。
(6) 与终端交互相关的信号。如用户关闭一个终端,或按下break键等情况。
下列宏常量表达式指定了标准的信号值:
Marcro | Signal |
SIGABRT | 异常终止,如调用abort(). |
SIGFPE | 如除0或操作结果溢出(不一定是浮点操作). |
SIGILL | 非法指令或无效的函数镜像,通常由于代码错误或执行数据引起. |
SIGINT | 交互式中断信号,通常由用户产生. |
SIGSEGV | 段冲突.访问非法存储空间时产生. |
SIGTERM | 发给本程序的中止信号. |
#include<stdio.h>
#include<sys/time.h>
#include<signal.h> void response(void);
int main()
{
struct itimerval my_timer;
long n_sec, n_usec;
my_timer.it_interval.tv_sec = ;
my_timer.it_interval.tv_usec = *;//300ms
my_timer.it_value.tv_sec = ; //2s
my_timer.it_value.tv_usec = ; setitimer(ITIMER_REAL, &my_timer, NULL); signal(SIGALRM,(__sighandler_t)&response);
while()
;
return ;
} void response(void)
{
printf("Receive signal!!\n");
}
上述代码片段将定时器初始值设为2s,循环值为300ms,则当setitimer函数执行以后2s产生SIGALRM中断,由signal函数指定中断处理函数为response();
2s之后,每隔300ms产生一次SIGALRM中断。