How to block all SIGNALS in thread WITHOUT using SIGWAIT?
With s = pthread_sigmask(SIG_BLOCK, &set, NULL);
, you're not blocking anything.
Use:
sigfillset(&set);
sets = pthread_sigmask(SIG_SETMASK, &set, NULL);
If you want to block every signal, or explicitly add the signals you want to block to the set
if you're using SIG_BLOCK.
After you've created the threads, you need to restore the signal mask, otherwise no threads will catch any signal.
However, looking at your previous question, it might be that the thread catching the signal doesn't handle being interrupted. That is, if you're blocked doing a syscall, and a signal arrives, that syscall gets aborted. Some operating systems defaults to automatically call the system call again, some returns an error and sets errno to EINTR, which the application must handle - and bad things might happen if that's not handled.
Instead, install your signal handlers with sigaction() instead of signal() , and set the SA_RESTART
flag, which will cause system calls to automatically restart in case it got aborted by a signal.
Lynton Grice
Updated on June 14, 2022Comments
-
Lynton Grice almost 2 years
I have a main application that spawns a seperate thread to process messages off a queue. I have an issue on AIX when I hit CTRL-C as it seems to make some "connection handles" in the thread become invalid. I do have a shutdown hook in the main program catching the SIGINT but on AIX it seems to somehow send a signal to the thread as well...although that is not really possible from what I hear...
Essentially I would like to know if I want the MAIN application to handle ALL signals I am interested in and have the thread/s NEVER handle any signals...is that "good practice"?
If so how can I NOT use "sigwait" in the thread...in fact I do not want any "signal code" in the thread/s...they must simply not receive any signals at all.
I have emptied out all the signals:
sigemptyset(&set);
And have set the SIG_BLOCK
s = pthread_sigmask(SIG_BLOCK, &set, NULL);
So here is a dummy test programe:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <errno.h> #define handle_error_en(en, msg) do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) static void * threadMainLoop(){ //Here I do not want the thread to use "sigwait".... while(running == TRUE){ //do some thread work and never have any signals come in } } void shutdownHook(int sig){ printf("\nCtrl-C pressed....shutdown hook in main...\n"); } void signalErrorHandler(int signum){ printf("\nSignal error handler in main...\n"); } int main(int argc, char *argv[]){ pthread_t thread; sigset_t set; int s; //Catch the following signals in the MAIN thread (void) signal(SIGINT, shutdownHook); (void) signal(SIGSEGV, signalErrorHandler); (void) signal(SIGBUS, signalErrorHandler); (void) signal(SIGILL, signalErrorHandler); (void) signal(SIGTERM, signalErrorHandler); (void) signal(SIGABRT, signalErrorHandler); sigemptyset(&set); //BLOCK all signals s = pthread_sigmask(SIG_BLOCK, &set, NULL); if (s != 0) handle_error_en(s, "pthread_sigmask"); s = pthread_create(&thread, NULL, &threadMainLoop, (void *) NULL); if (s != 0) handle_error_en(s, "pthread_create"); pause(); }
If I just create a thread and have, for example, the SIGINT signal handler in the MAIN thread but do NOT has the SIG_BLOCK set for the thread and the user hits CTRL-C....does the thread get affected at all even though the signal handler in the main thread runs? That seems to be what I am seeing on AIX ;-(
Thanks for the help, much appreciated
Lynton
-
Lynton Grice over 12 yearsHi there, but it I set "s = pthread_sigmask(SIG_BLOCK, &set, NULL);" and test with CTRL-C that thread does not receive the signal? That means it is blocking it? If I add "sigaddset(&set, SIGINT);" then the thread receives the signal. Forgive me if I am wrong here...I am still learning..;-) Thanks for the help ;-)
-
nos over 12 yearsUpdated the answer a bit.. The signal mask is the signals that cannot be raised. So if you do sigaddset(&set, SIGINT); pthread_sigmask(SIG_BLOCK, &set, NULL); , SIGINT will be set in the singnal mask, and that means the thread will not receive it. If you create a new thread, that thread inherits the signal mask from the thread that created it.
-
R.. GitHub STOP HELPING ICE over 12 yearsNote that if you want a new thread to start with signals masked (usually necessary to avoid nasty race conditions) you need to block the signals before calling
pthread_create
and then restore the old signal mask in the original thread afterpthread_create
returns. -
chill over 12 years@LyntonGrice, when you block the signal and it is sent to he thread, the signal remains pending to the thread. When you later unblock the thread, the signal will be delivered. If you don't want the signal delivered, you have to ignore it, not block it.