gvalero87
gvalero87

Reputation: 875

Send and catch signals to pthreads in C

I know how to send signals to child process in C using the kill(pid_t pid, int sig) function. What about sending signals to threads? is it possible?. If so, how to catch signals on the "child" thread. For example, if the main thread sends me a terminate signal, how can I in the other thread catch it.

Upvotes: 14

Views: 33716

Answers (4)

Jonathan Leffler
Jonathan Leffler

Reputation: 755044

Signals are sent to a process as a whole. Each signal sent to the process is received by a single thread (on behalf of the whole program). There are per-thread signal masks which influence whether a particular thread is eligible to handle a particular signal.

So, you need a signal handler - possibly in just one thread. Note that there are limits on what you're supposed to do in a thread's signal handler, though. Be wary of stepping far outside the promises made by the standard (which are minimal).

However, the pthread_kill() function can be used to send signals to other threads as long as the current thread can identify (has access to the thread ID values (pthread_t) that identify) the threads that are still executing within the process. You might decide to relay the signal to the other threads using a different signal number from the one originally caught (so one thread receives the external signal, but many threads receive the internal signal). Or you might use another Pthread synchronization or communication primitive instead of signals.

Upvotes: 11

Blagovest Buyukliev
Blagovest Buyukliev

Reputation: 43558

With POSIX threads, you have the functions pthread_cond_wait and pthread_cond_signal.

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
int pthread_cond_signal(pthread_cond_t *cond)

The signaled thread should block on a pthread_cond_wait call until another thread sends a signal using pthread_cond_signal, with the same condition variable.

Considering the analogy with signals delivered to processes, this is a bit different because the signaled thread has already suspended its execution waiting for a signal, unlike a process that simply gets interrupted and goes on.

Upvotes: 9

Adam Rosenfield
Adam Rosenfield

Reputation: 400652

Signals do not have thread affinity. They are handled completely asynchronously. When you specify a signal handler with signal(2) or sigaction(2), it's a global signal handler. When a signal is raised, the signal handler runs on top of the stack of whatever thread happens to be running at the time, and you can't control that.

It sounds like you want some other sort of interthread communication. The simplest way to do this is with a volatile shared variable:

volatile bool should_terminate = false;

void ChildThread()
{
    while(!should_terminate)
    {
        // do stuff
    }
}

void MainThread()
{
    // To terminate child thread:
    should_terminate = true;
}

If you need stronger concurrency control, look into mutexes, condition variables, and semaphores.

Upvotes: 3

bot403
bot403

Reputation: 2161

I'm not sure this is possible as it is platform and implementation dependant and I highly suggest you don't use signals to communicate between threads. Sometimes only a specific thread will receive signals and sometimes all threads receive signals.

Better thread communucation mechanisms exist like queues, semaphores, and locks.

Upvotes: 0

Related Questions