What stream processes the signal?

I have 2 threads (thread1 and thread2). And I have a signal location for SIGINT . Whenever a SIGINT occurs, stream 2 must process the signal. For this, I wrote a program below

 void sig_hand(int no) //signal handler { printf("handler executing...\n"); getchar(); } void* thread1(void *arg1) //thread1 { while(1) { printf("thread1 active\n"); sleep(1); } } void * thread2(void * arg2) //thread2 { signal(2, sig_hand); while(1) { printf("thread2 active\n"); sleep(3); } } int main() { pthread_t t1; pthread_t t1; pthread_create(&t1, NULL, thread1, NULL); pthread_create(&t2, NULL, thread2, NULL); while(1); } 

I compiled and ran the program. every 1 second “thread1 active” prints and every 3 seconds “thread2 active” prints.

Now I generated SIGINT . But it prints the messages "thread1 active" and "thread2 active" as above. I generated SIGINT again, now every 3 seconds only the message "thread2 active" is printed. I generated SIGINT again, now all threads are blocked.

So, I realized that for the first time the main thread executes a signal handler. The second time, thread1 executes a signal handler, and finally, thread 2 executes a signal handler.

How can I write code, like whenever a signal occurs, only thread2 should execute my signal handler?

+8
source share
2 answers

If you send a signal to a process, which thread in this process will process this signal is undefined.

According to pthread(7) :

POSIX.1 also requires that threads share a number of other attributes (i.e., these attributes are system-wide, not streaming):
...
- distribution of signals
...

POSIX.1 distinguishes the concepts of signals that are directed to the process as a whole and signals directed to individual threads. According to POSIX.1, a process-directed signal (sent using kill(2) , for example) must be processed by a single, arbitrarily selected thread in the process.


If you need a dedicated thread in your process to process some signals, here is an example from pthread_sigmask(3) shows you how to do this:

The program below blocks some signals in the main stream, and then creates a dedicated stream to extract these signals through sigwait (3). The following shell session demonstrates its use:

 $ ./a.out & [1] 5423 $ kill -QUIT %1 Signal handling thread got signal 3 $ kill -USR1 %1 Signal handling thread got signal 10 $ kill -TERM %1 [1]+ Terminated ./a.out 

Program source

 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <errno.h> /* Simple error handling functions */ #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) static void * sig_thread(void *arg) { sigset_t *set = arg; int s, sig; for (;;) { s = sigwait(set, &sig); if (s != 0) handle_error_en(s, "sigwait"); printf("Signal handling thread got signal %d\n", sig); } } int main(int argc, char *argv[]) { pthread_t thread; sigset_t set; int s; /* Block SIGQUIT and SIGUSR1; other threads created by main() will inherit a copy of the signal mask. */ sigemptyset(&set); sigaddset(&set, SIGQUIT); sigaddset(&set, SIGUSR1); s = pthread_sigmask(SIG_BLOCK, &set, NULL); if (s != 0) handle_error_en(s, "pthread_sigmask"); s = pthread_create(&thread, NULL, &sig_thread, (void *) &set); if (s != 0) handle_error_en(s, "pthread_create"); /* Main thread carries on to create other threads and/or do other work */ pause(); /* Dummy pause so we can test program */ } 
+16
source

Carefully read the signal (7) & pthread (7) & pthread_kill (3) & sigprocmask (2) & pthread_sigmask (3) -which, which you can use (to block SIGINT in unwanted threads). Read also the textbook .

Avoid using signals for communication or synchronization between threads. Consider, for example, mutexes ( pthread_mutex_lock, etc.) and conditional variables ( pthread_cond_wait, etc.).

If one of the threads starts an event loop (e.g. around poll (2) ...), consider using signalfd (2) .

+5
source

All Articles