1

I'm writing a multithreaded program which needs to be terminated with the following bash line:

killall -QUIT -w procname

I decided to use a thread to receive some signals I need to handle, like SIGQUIT and SIGUSR1, and to ignore SIGQUIT in the others. To ignore the signal I wrote this:

struct sigaction s;
s.sa_handler=SIG_IGN;
if((sigaction(SIGQUIT,&s,NULL))==-1) {   
    perror("sigaction");
    return -1;
    }

And I wrote the following code in the thread designated to wait for signals (handlerrno is a function to check errno and exit):

sigset_t threadset;
int err, sig;
if(sigfillset(&threadset)==-1) handlerrno("Sigfillset thread stats");
if(sigdelset(&threadset,SIGQUIT)==-1) handlerrno("Sigdelset thread stats");
if(sigdelset(&threadset,SIGINT)==-1) handlerrno("Sigdelset thread stats");
if(sigdelset(&threadset,SIGTERM)==-1) handlerrno("Sigdelset thread stats");
if(sigdelset(&threadset,SIGUSR1)==-1) handlerrno("Sigdelset thread stats");
if((err=pthread_sigmask(SIG_SETMASK,&threadset,NULL))!=0)        
   handlerror(err,"Set sigmask thread stats");
if((err=sigwait(&threadset,&sig))!=0) handlerror(err,"Sigwait");
//I handle the signals here

However, when I launch SIGQUIT from the shell, the thread designated to wait for the signals seems to be stuck in sigwait(), so I don't really know what happens and which thread gets the signal. Is anything wrong with the code? Thank you!

Gixuna
  • 86
  • 8

1 Answers1

1

Ignore masks are process-wide. After the sigaction call, SIQUIT will never become pending in any thread and sigwait will therefore block forever.

What you should do is block the signal in the main thread before creating any threads, so that child threads block it too (child threads inherit the signal mask of their parent thread).

The handling thread should then be able to dequeue the signal despite it being blocked.

(I'm not sure whether your choice of terminating signal is a good one. SIQUIT is normally sent via Ctrl+\ and is expected to create a core dump before terminating. Perhaps SIGTERM would be a better choice.)

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • Thanks! I need to terminate the process like this because this is an assignment for university, so our teacher gave us a test script to make sure the code works. Anyway, the thing is that the handling thread is spawned by the main thread, so if I block it in there the handling one blocks it too right? – Gixuna Aug 04 '17 at 13:28
  • Correct. And if no thread has it unblocked and you only have one sigwait call active in the process, the sigwait call should get it. – Petr Skocik Aug 04 '17 at 13:33