> Which thread receives signals in a application with multiple threads?
> Only the running one, the main thread or is this picked randomly?

Here's the deal: There are several flavors of signals.  I'll suggest a
canonical terminology by describing them.

Synchronous: A signal that is the result of a trap resulting from some
instruction executed by a particular thread.  For example, if you dereference
NULL you get a SIGSEGV from a page fault that can't be resolved.  This is
synchronous to the instruction stream of the thread, and this signal is
always delivered to the thread which triggered the exception.

Directed Asynchronous: A signal that is asynchronous to the instruction streams
of the threads in the process, but is directed at a particular thread.
Examples of such signals are SIGPROF, SIGVTALRM, and SIGCANCEL, which is
used by pthread_cancel().  These signals are always received by the thread
to which they are directed.  pthread_kill() would be another source of them.

Non-Directed Asynchronous: A signal that is asynchronous to the instruction
streams of the threads in the process and has no association with any thread.
The simplest example here is another process issuing a kill(2) to your
multi-threaded process's PID.  The receiver is the process, not any particular
thread.  The behavior of the kernel in this case is that we walk through the
list of threads, looking for a thread which does not have the signal blocked,
and make this thread receive the signal.  If everyone has it blocked, then
the signal remains pending until someone unmasks it.  So in effect the thread
receiving such a signal is "random" but with a rational programming model.

Namely, when writing multi-threaded code, what you want to do is arrange to
have a single thread handle all of your non-directed asynchronous signals.
The typical way to do this is to have one thread hang out in sigsuspend()
and every other thread in the process have its signal mask set up to 
block all signals.  The result will be that the sigsuspend() thread is the
only one available to receive the signal and is always ready to do so,
and therefore you can be assured of who is going to get the signal.

If you want to see an example of a daemon which does this, look at fmd(1M).
The set up for signals is at the end of usr/src/cmd/fm/fmd/common/fmd_main.c

Hope this helps,

-Mike

-- 
Mike Shapiro, Solaris Kernel Development. blogs.sun.com/mws/
_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code

Reply via email to