我使用timer_create() API实现了一个POSIX定时器,当定时器到期时会生成SIGUSR1信号,我已经编写了处理程序代码。现在的问题是,如果程序接收到另一个SIGUSR1信号,那么同样的信号处理程序将被调用和捕获。
是否有任何方法可以防止这种情况发生,使处理程序只能捕获由定时器生成的信号?
是否有任何方法可以防止这种情况发生,使处理程序只能捕获由定时器生成的信号?
这对你是否有用?(从 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
。否则将显示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);
不,没有简单的方法。如果您有其他东西与您的计时器一起生成SIGUSR1,请改用SIGUSR2来定时器。如果这不够,请使用一个实时信号来处理您的应用程序。
如果它必须能够处理来自计时器和其他源相同的信号,则取决于速度,数量,系统等等,您可以尝试在注册计时器之前设置时间戳,以确定计时器将大约何时退出,然后在信号处理程序中尝试推断是否在时间间隔内。我强烈建议不要使用此方法,而是重新设计您正在做的事情。
使用其他RT信号。请参考{{link1:在Linux中是否有创建用户定义信号的方法?}}上的答案。
struct sigaction sa;
改为一个数组(并且你要将所有这些变量重命名为有意义、可维护的名称;-) - Mawg says reinstate Monica