如何使用" setitimer()"设置多个警报功能调用

时间:2017-11-24 10:23:35

标签: c linux setitimer

我需要在同一个进程中设置多个间隔计时器(相同类型的警报:ITIMER_REAL)。所以我使用 setitimer()系统调用来创建3个警报,每个计时器都有独立的结构来保存时间间隔值。当任何计时器到期时,它会向调用进程发出SIGALRM信号,但我无法找到三个中的哪个计时器发出信号,我甚至都不知道所有计时器是否都在运行。有没有办法找到哪个计时器给出了信号...... 谢谢。

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

void timer_handler (int signum)
{
 static int count = 0;
 printf ("timer1 expired %d times\n", ++count);
}


int main ()
{   
    int m = 0;
     struct sigaction sa;
     struct itimerval timer1, timer2, timer3;

     memset (&sa, 0, sizeof (sa));

     sa.sa_handler = &timer_handler;

     sigaction (SIGALRM/*SIGVTALRM*/, &sa, NULL);

     timer1.it_value.tv_sec = 1;
     timer1.it_value.tv_usec = 0;
     timer1.it_interval.tv_sec = 5;
     timer1.it_interval.tv_usec = 0;

     timer2.it_value.tv_sec = 2;
     timer2.it_value.tv_usec = 0/* 900000*/;
     timer2.it_interval.tv_sec = 5;
     timer2.it_interval.tv_usec = 0/*900000*/;

     timer3.it_value.tv_sec = 3;
     timer3.it_value.tv_usec = 0/* 900000*/;
     timer3.it_interval.tv_sec = 5;
     timer3.it_interval.tv_usec = 0/*900000*/;

     setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer1, NULL);
     setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer2, NULL);
     setitimer (ITIMER_REAL/*ITIMER_VIRTUAL*/, &timer3, NULL);

    while (1)
    {
        //printf("\nin main  %d",m++);
        //sleep(1);
    }
}

2 个答案:

答案 0 :(得分:0)

如果我理解你的问题,你想知道不同计时器的状态。

在参考文献中,一个getitimer函数可用:

  

函数getitimer()填充curr_value指向的结构   用于指定的计时器的当前设置(其中一个)   ITIMER_REAL,ITIMER_VIRTUAL或ITIMER_PROF)。元素it_value是   设置为计时器剩余的时间量,如果是计时器则为零   被禁用。同样,it_interval设置为重置值。

您可以在Link

找到完整的参考资料

希望有所帮助

答案 1 :(得分:0)

否,每个进程只有一个ITIMER_REAL计时器。多次使用setitimer会覆盖先前的值,请参见man setitimer

  

一个进程只有三种计时器中的一种。

当您在示例代码中修改时间间隔时,您也可以看到

timer1.it_interval.tv_sec = 1;
timer2.it_interval.tv_sec = 2;

并使用nanosleep代替sleep,因为它可能会干扰SIGALRM

现在运行代码,您将只看到5秒的间隔。


您还可以通过提供第二个struct itimerval

来检索先前的设置值。
struct itimerval old1, old2, old3;
setitimer(ITIMER_REAL, &timer1, &old1);
setitimer(ITIMER_REAL, &timer2, &old2);
setitimer(ITIMER_REAL, &timer3, &old3);

old1将包含零值,因为这是您第一次使用setitimerold2包含it_interval = 1 sec,而old3包含it_interval = 2 secit_value会有所不同,具体取决于两次调用setitimer所经过的时间。

因此,如果需要多个计时器,则需要进行一些记账。每次计时器到期时,您都必须计算下一个计时器,然后相应地调用setitimer


或者,您可以考虑使用POSIX timers。这样可以创建多个计时器

  

程序可以使用timer_create()创建多个间隔计时器。

,还通过sigevent将一些ID传递给处理程序。尽管手册页末尾的example看起来更加复杂。