setitimer: 设置定时器间隔

时间:2022-11-11 00:16:04

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);

}