A thread can use sigwait to process the signal.
But if the main thread has already registered the processing function with Sig_handler, the thread also uses sigwait to process the signal, then who will deal with it first. Apue just wrote a bit about the operating system, here we do experiments to see which of Linux will handle.
#include <pthread.h> #include <signal.h> #include <unistd.h> #include <stdio.h> #include <
string.h> #include <stdlib.h> #include <stdio.h> int quitflag;
sigset_t Mask;
pthread_mutex_t lock = Pthread_mutex_initializer;
pthread_cond_t wait = Pthread_cond_initializer;
void * THR_FN (void * arg) {#if 1 int err, signo;
sigset_t Oldmask;
Sigemptyset (&mask);
Sigaddset (&mask, SIGINT);
Sigaddset (&mask, sigquit);
Sigaddset (&mask, Sigbus);
if (err = Pthread_sigmask (Sig_block, &mask, &oldmask))! = 0) {printf ("Sigblock error\n");
Exit (ERR); } for (;;)
{err = sigwait (&mask, &signo);
if (0! = Err) {printf ("sigwait failed\n");
Exit (ERR);
} switch (signo) {case sigbus:printf ("sigbus\n");
Break
DEFAULT:PRINTF ("Unexpected signal%d\n", signo);
Exit (1);
}} out0:if (Sigprocmask (Sig_setmask, &oldmask, NULL) < 0) {printf ("Sig_setmask error\n");
Exit (ERR); } #enDIF exit (0);
} static void Sigbus_handler (void* data) {printf ("Sigbug:sigbus_handler \ n");
Return
} static void Qemu_init_sigbus (void) {struct sigaction action;
memset (&action, 0, sizeof (action));
Action.sa_flags = Sa_siginfo;
Action.sa_sigaction = (void (*) (int, siginfo_t*, void*)) Sigbus_handler;
Sigaction (Sigbus, &action, NULL);
} int main (void) {int err;
pthread_t Tid;
Qemu_init_sigbus ();
Err = Pthread_create (&tid,null,thr_fn,0);
if (err! = 0) {printf ("Can not create thread\n");
Exit (ERR);
} exit (0);
}
Compiling code
GCC Test.c-o test-lpthread
Run results
./test
kill-7 ${main thread pid}
Sigbug:sigbus_handler kill-7 ${child thread pid}
Sigbug
As you can see, if the child thread has a handler function written in sigwait, then sigwait processing, the main thread is Sig_handler processing
I'm doing an experiment.
#include <pthread.h> #include <signal.h> #include <unistd.h> #include <stdio.h> #include <
string.h> #include <stdlib.h> #include <stdio.h> int quitflag;
sigset_t Mask;
pthread_mutex_t lock = Pthread_mutex_initializer;
pthread_cond_t wait = Pthread_cond_initializer; void * THR_FN (void * arg) {for (;;)
{sleep (5);
} exit (0);
} #if 1 static void Sigbus_handler (void* data) {printf ("Sigbug:sigbus_handler \ n");
Return
} static void Qemu_init_sigbus (void) {struct sigaction action;
memset (&action, 0, sizeof (action));
Action.sa_flags = Sa_siginfo;
Action.sa_sigaction = (void (*) (int, siginfo_t*, void*)) Sigbus_handler;
Sigaction (Sigbus, &action, NULL);
} #endif int main (void) {int err;
pthread_t Tid;
Qemu_init_sigbus ();
Err = Pthread_create (&tid,null,thr_fn,0);
if (err! = 0) {printf ("Can not create thread\n");
Exit (ERR);
} pthread_mutex_lock (&lock); while (Quitflag = = 0) {Pthread_conD_wait (&wait, &lock);
} pthread_mutex_unlock (&lock);
Quitflag = 0;
Exit (0);
}
Run results
./test
kill-7 ${main thread pid}
Sigbug:sigbus_handler kill-7 ${child thread pid}
Sigbug:sigbus_handler
If there is no response signal processing function in the sub-thread, the system will uniformly choose the number of signal processing functions sig_handler in the main process.
Sum up
The Linux kernel does not have special handling cases:
If there is a sigwait handler in the child thread, then sigwait processing, the main thread is Sig_handler processing
If there is no response signal processing function in the sub-thread, the system will uniformly choose the number of signal processing functions sig_handler in the main process.