I am implementing a simple timer that throws a RT signal upon expiration. What I want to do is to register a signal handler (using sigaction) that gets called when the signal occurs. Meanwhile the main code waits until the signal is called using sigwaitinfo.
Implementing either a signal handler or sigwaitinfo exclusively works fine. However when both are used, the signal handler is never called. I tried switching the order; i.e. registering the handler before blocking the signal. Makes no difference.
Here is the code
// gcc -Wall -o sigwait_example sigwait_example.c -lrt
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#define install_handler(sig,sa) if( sigaction(sig, &sa, NULL) 开发者_运维知识库== -1 ){ \
perror("sigaction"); }
#define SIG SIGRTMIN+1
volatile int flag=0;
void handler(int signum){
flag++;
}
int main(void){
struct itimerspec its;
sigset_t blocked;
siginfo_t si;
timer_t timerid;
struct sigevent evt;
struct sigaction sa;
evt.sigev_notify = SIGEV_SIGNAL;
evt.sigev_signo = SIG;
evt.sigev_value.sival_ptr = &timerid;
if ( timer_create(CLOCK_REALTIME, &evt, &timerid) ){
perror("timer_create");
}
//setup timer
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0.1*1E9;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
//arm the timer
if ( timer_settime(timerid, 0, &its, NULL) )
perror("timer_settime");
sigemptyset(&blocked);
sigaddset(&blocked, SIG);
//add SIG to blocked signals
pthread_sigmask(SIG_BLOCK, &blocked, NULL);
sa.sa_flags = SA_SIGINFO; //use this flag to set custom handler
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
install_handler(SIG,sa);
while ( sigwaitinfo(&blocked, &si) == -1 && errno == EINTR );
printf("received signal: %s, flag=%d\n",strsignal(si.si_signo),flag);
//while(flag==0) sleep(1); //use this when only signal handler is used
timer_delete(timerid);
return 0;
}
I am doing this mostly for educational purposes, since I need to learn as much as possible about how threads are sent/blocked as I will be using them in threads.
It's not possible because sigwaitinfo()
removes the signal from the queue.
You can, however, use sigaction(SIG, NULL, &sa)
to retrieve the sigaction struct of this signal and execute the handler.
精彩评论