1

我需要在同一进程中设置多个间隔计时器(相同类型的警报: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);
    }
}
4

2 回答 2

1

不,每个进程只有一个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将包含零值,因为这是您第一次使用setitimer. old2包含it_interval = 1 secold3包含it_interval = 2 sec。s 会有所不同,具体it_value取决于调用setitimer.

所以,如果你需要多个计时器,你需要做一些簿记。每次计时器到期时,您必须计算下一个计时器并setitimer相应地调用。


作为替代方案,您可以查看POSIX timers。这允许创建多个计时器

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

并通过 . 将一些 id 传递给处理程序sigevent。尽管手册页末尾的示例看起来更复杂一些。

于 2018-06-22T17:50:01.220 回答
0

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

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

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

你可以在这里找到完整的参考链接

希望有帮助

于 2017-11-24T10:26:58.183 回答