signal can be received in any threads or main program itself. i have created one auxiliary thread from main program. so there is two thread in my program 1. main thread (process itself) 2. Auxiliary Thread. I just want that whenever signal arrived in my auxiliary thread, that should send signal to my main thread (program). i am using pthread_kill(main_threadid, sig) to send signal from signal handler register inside auxiliary thread. but. i observe each time signal send to main thread received to auxiliary child itself and signal handler falls in loop of receiving sending signal.
#include <pthread.h> #include <signal.h> #include <stdio.h> #include <unistd.h> // global variable pthread_t main_threadId; struct sigaction childpsa; // Signal Handler for Auxiliary Thread void signalHandler_Child(int param) { printf("Caught signal: %d in auxiliary Thread", param); pthread_kill(main_threadId, param); } void *childFun(void *arg) { childpsa.sa_handler = signalHandler_Child; sigaction(SIGTERM, &childpsa, NULL); sigaction(SIGHUP, &childpsa, NULL); sigaction(SIGINT, &childpsa, NULL); sigaction(SIGCONT, &childpsa, NULL); sigaction(SIGTSTP, &childpsa, NULL); while (1) { // doSomething in while loop } } int main(void) { main_threadId = pthread_self(); fprintf(stderr, "pid to signal %dn", getpid()); // create a auxiliary thread here pthread_t child_threadId; int err = pthread_create(&child_threadId, NULL, &childFun, NULL); while (1) { // main program do something } return 1; }
say I am sending SIGINT to process from terminal using its process id.
Advertisement
Answer
From Advanced Programming in the Unix Environment:
Each thread has its own signal mask, but the signal disposition is shared by all threads in the process. This means that individual threads can block signals, but when a thread modifies the action associated with a given signal, all threads share the action. Thus, if one thread chooses to ignore a given signal, another thread can undo that choice by restoring the default disposition or installing a signal handler for the signal.
The sigaction
call is setting the signal disposition for the entire process (and all threads in that process).
When you send a signal to the process, any thread (but only 1 thread) that hasn’t blocked the signal can receive it (although from my limited experience the main thread is typically preferred). In your code, the main thread is likely getting the signal, running the signal handler and then promptly sending the signal to itself again.
If you would like your single auxiliary thread to handle all signals for your process, you can use pthread_sigmask in your main thread to block the signals in question:
sigset_t set; sigemptyset(&set); sigaddset(&set, SIGTERM); sigaddset(&set, SIGHUP); sigaddset(&set, SIGINT); sigaddset(&set, SIGCONT); sigaddset(&set, SIGTSTP); pthread_sigmask(SIG_BLOCK, &set, NULL);
This will ensure the signal isn’t delivered to that thread. If you do this before pthread_create you’ll need to unblock them in your auxiliary thread.
You could then use non-signal inter-thread communication mechanism to communicate back to the main thread.