我正在尝试让信号处理程序在不退出程序的情况下停止计时器。我该怎么办?我希望StopTimer处理信号以停止计时器
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#define INTERVAL 2 // number of seconds to go off
int main(int argc, char* argv[]) {
TimerSet(INTERVAL);
while(1)
{
// do stuff
}
return 0;
}
void TimerSet(int interval)
{
printf("starting timer\n");
struct itimerval it_val;
// interval value
it_val.it_value.tv_sec = interval;
it_val.it_interval = it_val.it_value;
// on SIGALRM, close window
if (signal(SIGALRM, TimerStop) == SIG_ERR)
{
perror("Unable to catch SIGALRM");
exit(1);
}
// set interval timer, returns SIGALRM on expiration
if (setitimer(ITIMER_REAL, &it_val, NULL) == -1)
{
perror("error calling setitimer()");
exit(1);
}
}
void TimerStop(int signum)
{
printf("Timer ran out! Stopping timer\n");
exit(signum);
}
我试图将setitimer间隔设置为0,但我不确定如何在TimerStop信号处理函数中使用相同的定时器
答案 0 :(得分:2)
根据手册:
Timers decrement from it_value to zero, generate a signal, and reset to
it_interval. A timer which is set to zero (it_value is zero or the timer
expires and it_interval is zero) stops.
Both tv_sec and tv_usec are significant in determining the duration of a
timer.
因此,如果在setitimer()调用之前将interval设置为零,则可以将timer设置为仅运行一次(感谢Duck的注释)。
答案 1 :(得分:2)
只需将it_interval
设置为零,即可获得一次性定时器。您不需要在处理程序中对它执行任何操作。
例如,有了这个:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
#define INTERVAL 2 // number of seconds to go off
void TimerStop(int signum) {
printf("Timer ran out! Stopping timer\n");
}
void TimerSet(int interval) {
printf("starting timer\n");
struct itimerval it_val;
it_val.it_value.tv_sec = interval;
it_val.it_value.tv_usec = 0;
it_val.it_interval.tv_sec = 0;
it_val.it_interval.tv_usec = 0;
if (signal(SIGALRM, TimerStop) == SIG_ERR) {
perror("Unable to catch SIGALRM");
exit(1);
}
if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
perror("error calling setitimer()");
exit(1);
}
}
int main(int argc, char *argv[]) {
TimerSet(INTERVAL);
while (1) {
// do stuff
}
return 0;
}
消息"Timer ran out! Stopping timer"
只会出现一次,您的计时器将在没有您执行任何操作的情况下停止。
请注意,您需要填写tv_usec
struct itimerval
成员,而您当前的代码不会这样做。如果不这样做,it_interval
极不可能为零,您的计时器将永远不会停止。
printf()
以及其他标准IO函数,从信号处理程序调用是不安全的,尽管在这种特殊情况下它不会给你带来任何问题,因为主代码只是坐在一个循环而没有做任何事情。
另外,假设您故意调用signal()
- sigaction()
是设置处理程序的推荐方法。 setitimer()
现在也已过时,建议使用timer_settime()
。