Love Bisaria
Love Bisaria

Reputation: 167

Not able to catch SIGINT signal in a multithreaded program

#include <stdio.h>
#include <pthread.h>
#include <signal.h>

sigset_t set;
int sigint_signal = 0;
pthread_t monitor_thread, demo_thread;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

void *monitor()
{

    while(1)
    {
        sigwait(&set, NULL);
        pthread_mutex_lock(&m);
        printf("__SIGINT received__\n");
        sigint_signal = 1;
        pthread_cancel(demo_thread);
        pthread_mutex_unlock(&m);
    }

}

void *demo_function(){
    while(1){
        pthread_mutex_lock(&m);
        fprintf(stdout, "__Value of SIGNAL FLAG %d:__\n",sigint_signal);
        pthread_mutex_unlock(&m);
    }
    return NULL;
}

int main(){

    sigemptyset(&set);
    sigaddset(&set,SIGINT);
    pthread_sigmask(SIG_BLOCK,&set,0);

    pthread_create(&monitor_thread, 0, monitor, NULL);
    pthread_create(&demo_thread, 0, demo_function, NULL);

    pthread_join(demo_thread, NULL);
    return 0;
}

monitor_thread is the thread that is continuously running to catch the SIGINT signal. On receiving the signal it must cancel the other thread and end. SIGINT is getting received, this can be verified with the value of the variable sigint_signal which becomes 1 once the signal is received.But pthread_cancel is not getting executed, because once the value of sigint_signal is changed to 1, the demo_thread keeps on running.Please help.

Upvotes: 0

Views: 412

Answers (1)

John Zwinck
John Zwinck

Reputation: 249582

Read the documentation: http://man7.org/linux/man-pages/man3/pthread_cancel.3.html

There you will see that pthread_cancel is not guaranteed to instantly kill the thread, but rather that it depends on the state of that thread. By default, cancellation can only occur at cancellation points, which do include write() which may indirectly include printf().

Anyway, the real solution is to not use pthread_cancel at all, and instead use sigint_signal as the while loop condition in demo_function.

As for why pthread_cancel is a bad idea, this is because in general, functions are usually not written in a way that they are prepared to die. It's hard to reason about resource management in a context where execution might be terminated asynchronously.

Upvotes: 1

Related Questions