Skip to content
Advertisement

Linux: effect of signal on multiple threads

I don’t think this is a duplicate. I have a very specific question about what happens to other threads when a signal handler is invoked.

I have a multithreaded program that plays with hardware. On getting SIGTERM (from a parent process), I want the signal handler to set the state of the hardware to a given state, and exit(1). I understand that, since I didn’t play with signal masks, the main thread will process the signal. But it’s a multiprocessor system (raspberry pi) and the other threads are all running at high priority relative to main. They are probably asleep but they might also be touching hardware.

If all the other threads freeze on the arrival of a signal, I’m fine – I call exit() directly from the signal handler and the other threads will never run again. But if they can run independently, they might fuss with the hardware after I’ve set the desired state in the handler, but before I exit. And I can’t find documentation that describes the effect. If “freeze everything but the signal handler” isn’t the default, is there a way to get that behaviour?

I can redesign the code to put all the hardware handling in one thread, and make that thread handle the interrupts, but it’s inconvenient – the thread layout I have now does good division of labor and each thread knows what hardware it can touch and when. I would rather not redesign.

Advertisement

Answer

The other threads will continue to run while the signal-handling thread is running. I don’t know of any freeze-everything mechanism.

However, if you have multiple threads manipulating the hardware, it seems like you should have some kind of mutual exclusion mechanism anyway. In effect:

pthread_mutex_lock(&hardware_lock);
fiddle_with_hardware();
pthread_mutex_unlock(&hardware_lock);

Then you can just have your signal-handling thread acquire the lock, reset the hardware state and call exit without releasing the lock. The exit call will terminate all threads and since the lock is held, no other thread would be able to mess with the hardware prior to terminating.

If you have multiple threads all manipulating discrete portions of the total hardware state, you can create a separate lock for each state portion. Then have your signal handling thread acquire all of the locks before setting the final hardware state and calling exit. Since in ordinary operation, there will be only one thread attempting to access each discrete portion of the state, there should be no measurable performance impact from the additional locking.

One other thing. I don’t think it’s accurate that “since I didn’t play with signal masks, the main thread will process the signal.” From pthreads(7):

According to POSIX.1, a process-directed signal (sent using kill(2), for example) should be handled by a single, arbitrarily selected thread within the process.

That means you should be using pthread_sigmask to ensure that the SIGTERM is directed to the main thread.

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