了解程序的输出

时间:2019-02-18 15:47:46

标签: c

我正在查看以下堆栈交换问题:how to call a function automatically at regular intervals?

我尝试在第一个答案中运行代码

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

 /* Install timer_handler as the signal handler for SIGVTALRM. */
 memset (&sa, 0, sizeof (sa));
 sa.sa_handler = &timer_handler;
 sigaction (SIGVTALRM, &sa, NULL);

 /* Configure the timer to expire after 250 msec... */
 timer.it_value.tv_sec = 0;
 timer.it_value.tv_usec = 250000;
 /* ... and every 250 msec after that. */
 timer.it_interval.tv_sec = 0;
 timer.it_interval.tv_usec = 250000;
 /* Start a virtual timer. It counts down whenever this process is
   executing. */
 setitimer (ITIMER_REAL, &timer, NULL);

 /* Do busy work. */
 while (1);
}

我不知道它在做什么。它似乎在2500毫秒后打印“闹钟”,但是我不知道这是怎么可能的,因为没有任何打印语句可以达到这种效果。我如何使其像预期的那样每2500毫秒增加计数器?

1 个答案:

答案 0 :(得分:5)

ITIMER_REAL发送SIGALRM而不发送SIGVTALRM。 更改信号即可使用。

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

 /* Install timer_handler as the signal handler for SIGVTALRM. */
 memset (&sa, 0, sizeof (sa));
 sa.sa_handler = &timer_handler;
 sigaction (SIGALRM, &sa, NULL);

 /* Configure the timer to expire after 250 msec... */
 timer.it_value.tv_sec = 0;
 timer.it_value.tv_usec = 250000;
 /* ... and every 250 msec after that. */
 timer.it_interval.tv_sec = 0;
 timer.it_interval.tv_usec = 250000;
 /* Start a virtual timer. It counts down whenever this process is
   executing. */
 setitimer (ITIMER_REAL, &timer, NULL);

 /* Do busy work. */
 while (1);
}

(通常,在信号处理程序中使用printf是一个坏主意,因为printf并不是异步信号安全的,但是在您的情况下这并不危险,因为您正在中断 是异步信号安全的常规上下文代码(即繁忙循环),尽管POSIX似乎不能保证此特殊异常,但为确保绝对安全,您应避免使任何信号处理程序中的异步信号不安全调用,并将printf替换为write(1, ...)。)