timer_create() 无法在处理程序函数中捕获信号
timer_create() not able to catch a signal in handler function
我在这里尝试实现一个定时器,比如 0-10 秒和每个 2 秒的间隔,所以我需要每 2 秒(总共 5 次)生成一个中断,说 2 秒已完成。我一直在使用 printf() 交叉检查 handler() 函数。但是我无法达到预期的效果result.please如果有人知道的话请联系我。
提前致谢。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#define SIGTIMER (SIGRTMAX)
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
void handler(int sig, siginfo_t *si, void *uc)
{
printf("Caught signal %d\n", sig);
}
int
main(int argc, char *argv[])
{
timer_t timerid;
struct sigevent sev;
struct itimerspec its;
struct itimerspec oitval;
struct sigaction sa;
/* Establish handler for timer signal */
printf("Establishing handler for signal %d\n", SIGTIMER);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGTIMER, &sa, NULL) == -1)
errExit("sigaction");
/* Create the timer */
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGTIMER;
sev.sigev_value.sival_ptr = &timerid;
if (timer_create(CLOCK_REALTIME, &sev, &timerid) == 0)
{
printf("timer ID is 0x%lx\n", (long) timerid);
/* Start the timer */
its.it_value.tv_sec = 10;
its.it_value.tv_nsec =0;
its.it_interval.tv_sec = 2;
its.it_interval.tv_nsec = 0;
if (timer_settime(timerid, 0, &its, &oitval) == -1)
errExit("timer_settime");
}
else
{
errExit("timer_create");
}
return 0;
}
首先你应该正确设置超时:
/* Start the timer */
its.it_value.tv_sec = 2;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 2;
its.it_interval.tv_nsec = 0;
it_value
是第一次触发之前的持续时间,it_interval
是所有后续触发之间的时间。参见 here。然后,你不应该从 main()
return 因为它会导致进程退出并且你将无法观察到计时器滴答声。您需要以某种方式阻止执行,例如
while(1) sleep(INT_MAX);
每次滴答 sleep()
returns 后 errno
设置为 EINTR
所以我们应该将其包装到循环中以允许计时器继续进行。稍后您可以决定何时离开此循环并退出。
P.S。从信号处理程序使用 printf()
不是一个好主意。你应该非常小心你在那里做什么。最好只写入某个全局变量并立即 return。并且可以在 sleep()
之后立即测试该变量,让您知道是否应该再次入睡或 return.
我在这里尝试实现一个定时器,比如 0-10 秒和每个 2 秒的间隔,所以我需要每 2 秒(总共 5 次)生成一个中断,说 2 秒已完成。我一直在使用 printf() 交叉检查 handler() 函数。但是我无法达到预期的效果result.please如果有人知道的话请联系我。
提前致谢。
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#define SIGTIMER (SIGRTMAX)
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
void handler(int sig, siginfo_t *si, void *uc)
{
printf("Caught signal %d\n", sig);
}
int
main(int argc, char *argv[])
{
timer_t timerid;
struct sigevent sev;
struct itimerspec its;
struct itimerspec oitval;
struct sigaction sa;
/* Establish handler for timer signal */
printf("Establishing handler for signal %d\n", SIGTIMER);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGTIMER, &sa, NULL) == -1)
errExit("sigaction");
/* Create the timer */
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGTIMER;
sev.sigev_value.sival_ptr = &timerid;
if (timer_create(CLOCK_REALTIME, &sev, &timerid) == 0)
{
printf("timer ID is 0x%lx\n", (long) timerid);
/* Start the timer */
its.it_value.tv_sec = 10;
its.it_value.tv_nsec =0;
its.it_interval.tv_sec = 2;
its.it_interval.tv_nsec = 0;
if (timer_settime(timerid, 0, &its, &oitval) == -1)
errExit("timer_settime");
}
else
{
errExit("timer_create");
}
return 0;
}
首先你应该正确设置超时:
/* Start the timer */
its.it_value.tv_sec = 2;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 2;
its.it_interval.tv_nsec = 0;
it_value
是第一次触发之前的持续时间,it_interval
是所有后续触发之间的时间。参见 here。然后,你不应该从 main()
return 因为它会导致进程退出并且你将无法观察到计时器滴答声。您需要以某种方式阻止执行,例如
while(1) sleep(INT_MAX);
每次滴答 sleep()
returns 后 errno
设置为 EINTR
所以我们应该将其包装到循环中以允许计时器继续进行。稍后您可以决定何时离开此循环并退出。
P.S。从信号处理程序使用 printf()
不是一个好主意。你应该非常小心你在那里做什么。最好只写入某个全局变量并立即 return。并且可以在 sleep()
之后立即测试该变量,让您知道是否应该再次入睡或 return.