Skip to content
Advertisement

pthread_kill() not sending signal to main thread (main program)

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.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement