我正在查看以下堆栈交换问题: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毫秒增加计数器?
答案 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, ...)
。)