我正在看这个堆栈交换问题:如何定期自动调用函数?
我尝试在第一个答案中运行代码
#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);
}
Run Code Online (Sandbox Code Playgroud)
我不明白它在做什么.它似乎在2500毫秒后打印"闹钟",但我不明白这是怎么回事,因为没有这种效果的打印声明.我如何让它每2500毫秒增加计数器,就像它应该的那样?
ITIMER_REALSIGALRM不发送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);
}
Run Code Online (Sandbox Code Playgroud)
(一般情况下,这是一个坏主意,printf在信号处理,因为printf不是异步信号安全的,但在你的情况下,它不应该是危险的,因为你经常中断上下文代码是异步信号安全的(即尽管如此,POSIX似乎不能保证这个特殊的例外,所以为了完全安全,你应该避免在信号处理程序中进行任何异步信号不安全的调用,并printf用a 代替write(1, ...).)