Why does Unix deliver signals this way?

1

In Unix, when signals are posted, and the receiving process is running more than one thread, at first a thread is chosen to carry out the signal handling routine.

I don't understand why that is necessary or even makes sense. Doesn't the signal handling routine need it's own stack, register set, etc., anyway?

artistoex

Posted 2011-12-05T19:38:09.553

Reputation: 3 353

Answers

3

Sure, it needs its own stack and register set. But what thread context it's running in matters too. For one thing, that controls what work gets interrupted while the signal is processed.

For example, suppose thread A is holding a recursive lock and has changed some critical structure to an inconsistent state. That's fine though, because it won't release the lock until it returns those structures to a consistent state.

Now, say the signal interrupts thread A, and the signal handler goes to acquire the lock to check that critical structure. It gets the lock, because it's the thread that already holds the lock and the lock is recursive. Since it just got the lock that protects the critical structure, it expects to be able to access it and find it in an consistent state. But, of course, it's in a inconsistent state. Boom! You just crashed.

So in this case, the signal handler must always go to a thread that never acquires that lock. That way, when the signal handler acquires the lock, it is sure that no other code holds that lock and thus the structure must be in a consistent state.

It is common in multi-threaded code to have one thread whose sole purpose is to catch all external signals sent to the program. It handles the signals one-by-one, so the signal never interrupts code that might hold a lock.

David Schwartz

Posted 2011-12-05T19:38:09.553

Reputation: 58 310

Thank you for answering this question, too :-) So you better not choose the wrong thread? All the more does carrying out a signal in the context of a thread sound like a curse rather than a bless. Why choose a context at all? – artistoex – 2011-12-05T20:48:30.753

Well, if you need to acquire locks, you need a thread context in which to acquire them because that's how the locks are designed. As I said, a simple and common solution is to have one thread just to accept external signals, and you accept them synchronously and process them one at a time from a context known to be safe. All your other threads can then block those signals. The UNIX signal mechanism predates multi-threading, and they don't fit as nicely as they could. – David Schwartz – 2011-12-05T21:09:44.487

So I should read about locks in detail to understand this. Thank you! – artistoex – 2011-12-07T09:40:40.670