setitimer: 设置定时器间隔¶
setitimer 系统调用是 alarm 系统调用的衍生。它会预设在指定的时间之后发送信号。
一个程序可以利用 setitimer 设置三种不同的定时器:
- 如果定时器代码是 ITIMER_REAL,当指定的挂钟时间消耗完时,向进程发送一个 SIGALRM 信号。
- 如果定时器代码是 ITIMER_VIRTUAL,当进程执行完特定的时间时将会收到一个 SIGVTALRM 信号。进程没有被执行时(就是说,在内核或者另外一个进程运行时),时间不计数。
- 如果定时器代码是 ITIMER_PROF,不论进程在执行用户态代码或内核态系统调用时,如果指定时间消耗完都将收到一个 SIGPROF 信号。
setitimer 的第一个参数是定时器代码,指明设置哪种定时器。第二个参数是一个指向 struct itimerval 对象的指针,指定定时器的新设置。第三个参数,如果不是 NULL, 则是一个指向另一个 structitimerval 对象的指针,接收旧定时器的设置。
一个 struct itimerval 变量由两部分构成:
- it_value 是一个 struct timeval 域,包含了直到定时器到时并发送信号的时间。如果它是 0 则代表定时器被禁用。
- it_interval 是另一个 struct timeval 域,包含了定时器终止后的重设值。如果是 0,这个定时器在终止后将失效,否则这个定时器在指定间隔后被重复启用。
struct timeval 类型在8.7小节“gettimeofday: 挂钟时间”里有详细描述。
代码 8.11 描述了如何使用 setitimer 跟踪一个程序的执行时间。一个定时器配置为每 250 毫秒到时(expire)并发送一个 SIGVTALRM 信号。
代码8.11 (itemer.c) 定时器实例
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
void timer_handler (int signum)
{
static int count = 0;
printf (“timer expired %d times\n”, ++count);
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
/* 设置 timer_handler 作为 SIGVTALRM 的信号句柄。*/
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGVTALRM, &sa, NULL);
/* 配置计时器在计时满250毫秒后中止…… */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
/*……并且此后每隔250毫秒重复上述操作。 */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;
/* 开始虚拟定时器。从程序开始执行起倒计时。*/
setitimer (ITIMER_VIRTUAL, &timer, NULL);
/* 开始穷忙 */
while (1);
}