linux下间隔计时器

sleep函数和alarm函数的定时单位都是秒,这个时间精度在大部分情况下都是够用的。但也有许多时候,需要更高的时间精度,这时sleep函数和alarm函数就显得无所适从了。而linux下的间隔计时器,则可以实现这样的任务。

 

 

1. 间隔计时器两个特点

 

  • 精度更高,可达微秒
  • 有三个独立的计时器:真实、进程、实用

 

2. 每个计时器有两种工作模式:初始时间和重复间隔

  • 初始时间(it_value):是指从本次设定开始,经过初始时间设定的时间长度后,计时器到点响应,可见是一次性的。
  • 重复间隔(it_interval):是指当计时器到点响应一次后,在经过多么长时间,再次响应,是循环的。
  • it_value和it_interval是结构体中的两个成员,谁的值为0,谁的功能就没有激活

 

3. 三种计时器:真实、进程、实用

  • ITIMER_REAL真实计时器:不管程序工作在用户态还是核心态,都进行记录。当计时器到点时,发送SIGALRM信号。
  • ITIMER_VIRTUAL进程时间:只记录用户态时间。到点时,发送SIGVTALRM消息。
  • ITIMER_PROF:在进程运行于用户态或由进程调用陷入核心态时计时。到点时,发送SIGPROF。

 

4. 示例程序及注释

这是一个从10开始倒计数的程序,时间间隔为0.5秒。

间隔计时器

[c]

#include<stdio.h>
#include<sys/time.h>
#include<signal.h>

int main()
{
//声明信号处理函数
void countdown(int);

//SIGALRM是由ITIMER_REAL真实计时器到点产生的
//将它与信号处理函数countdown绑定
signal(SIGALRM,countdown);

//set_ticker是我自定义的函数
//用来设定500毫秒的间隔
if( set_ticker(500) == -1 )
perror("set_ticker");
else
//主程序陷入死循环
//在到点之前,进程都出于挂起状态
while(1)
{
pause();
}
return 0;
}

//信号处理函数
//每到0.5秒计时到达时
//就从10开始倒数一个数
//数完后退出程序
void countdown(int signum)
{
static int num = 10;
printf("%d..",num--);
fflush(stdout);
if(num<0){
printf("DONE!n");
exit(0);
}
}

//设定计时器,用到结构体itimerval
//修改itimerval,通过setitimer更新
//it_interval、it_interval谁不为0,谁就激活
//从而实现定时功能
int set_ticker(int n_msecs)
{
struct itimerval new_timeset;
long n_sec,n_usecs;

//要将秒转换成秒和微秒,分别储存
n_sec = n_msecs/1000;
n_usecs = (n_msecs % 1000) * 1000L;

//修改结构体
new_timeset.it_interval.tv_sec = n_sec;
new_timeset.it_interval.tv_usec= n_usecs;

new_timeset.it_interval.tv_sec = n_sec;
new_timeset.it_value.tv_usec= n_usecs;

//更新、激活计时器
return setitimer(ITIMER_REAL,&new_timeset,NULL);
}

[/c]