定时器和信号中的问题

我已经使用timer_create()API实现了一个POSIX计时器,当计时器到期时,这将产生SIGUSR1,我已经放置了一个处理程序代码。 现在的问题是,如果这个程序收到另一个SIGUSR1,那么同样的信号处理程序将被调用并被捕获。

有什么办法来防止这种情况,以便处理程序可以捕获只有计时器产生的信号?

Solutions Collecting From Web of "定时器和信号中的问题"

这会为你工作吗? (修改了timer_create手册页中示例的代码。)

 #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <signal.h> #include <time.h> #define CLOCKID CLOCK_REALTIME #define SIG SIGUSR1 timer_t timerid; static void handler(int sig, siginfo_t *si, void *uc) { if(si->si_value.sival_ptr != &timerid){ printf("Stray signal\n"); } else { printf("Caught signal %d from timer\n", sig); } } int main(int argc, char *argv[]) { struct sigevent sev; struct itimerspec its; long long freq_nanosecs; sigset_t mask; struct sigaction sa; printf("Establishing handler for signal %d\n", SIG); sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = handler; sigemptyset(&sa.sa_mask); sigaction(SIG, &sa, NULL); sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIG; sev.sigev_value.sival_ptr = &timerid; timer_create(CLOCKID, &sev, &timerid); /* Start the timer */ its.it_value.tv_sec = 10; its.it_value.tv_nsec = 0; its.it_interval.tv_sec = its.it_value.tv_sec; its.it_interval.tv_nsec = its.it_value.tv_nsec; timer_settime(timerid, 0, &its, NULL); sleep(100); exit(EXIT_SUCCESS); } 

当来自定时器的信号被Caught signal 10 from timer时从定时器Caught signal 10 from timer将被显示。 否则将显示Stray signal

问题是你是否真的需要使用信号。 您可能会想到使用计时器到期时将会调用的回调函数:

 void cbf(union sigval); struct sigevent sev; timer_t timer; sev.sigev_notify = SIGEV_THREAD; sev.sigev_notify_function = cbf; //this function will be called when timer expires sev.sigev_value.sival_ptr = (void*) arg;//this argument will be passed to cbf timer_create(CLOCK_MONOTONIC, &sev, &timer); 

回调函数将在新线程中调用。

不,没有简单的方法。 为什么不用SIGUSR2来代替定时器呢?如果你还有别的东西和你的定时器一起产生SIGUSR1的话。 如果这还不够,请为您的应用程序使用其中一个实时信号。

如果它必须能够处理来自定时器和其他信号源的相同信号,那么取决于定时器何时会近似退出,在注册定时器之前,可以尝试设置时间戳的速度,多少,系统等等,然后在信号处理程序中尝试推断是否在时间范围内。 我强烈建议不要使用这种方法,而是重新设计你正在做的事情。

使用另一个RT信号。 看到的答案是否有任何方法来在Linux中创建一个用户定义的信号?