The call to sigprocmask() in a multithreaded process is equivalent to a call to pthread_sigsetmask(). See the sigprocmask(2) page for more information.
pthread_kill(3T) is the thread analog of kill(2)--it sends a signal to a specific thread.This, of course, is different from sending a signal to a process. When a signal is sent to a process, the signal can be handled by any thread in the process. A signal sent by pthread_kill() can be handled only by the specified thread.
Note than you can use pthread_kill() to send signals only to threads in the current process. This is because the thread identifier (type thread_t) is local in scope--it is not possible to name a thread in any process but your own.
Note also that the action taken (handler, SIG_DFL, SIG_IGN) on receipt of a signal by the target thread is global, as usual. This means, for example, that if you send SIGXXX to a thread, and the SIGXXX signal disposition for the process is to kill the process, then the whole process is killed when the target thread receives the signal.
For multithreaded programs, sigwait(2) is the preferred interface to use, because it deals so well with aysynchronously-generated signals.
sigwait() causes the calling thread to wait until any signal identified by its set argument is delivered to the thread. While the thread is waiting, signals identified by the set argument are unmasked, but the original mask is restored when the call returns.
All signals identified by the set argument must be blocked on all threads, including the calling thread; otherwise, sigwait() may not work correctly.
Use sigwait() to separate threads from asynchronous signals. You can create one thread that is listening for asynchronous signals while your other threads are created to block any asynchronous signals that might be set to this process.
Two versions of sigwait() are available in the Solaris 2.5 release: the new Solaris 2.5 version, and the POSIX.1c version. New applications and libraries should use the POSIX standard interface, as the Solaris version might not be available in future releases.
The new Solaris 2.5 sigwait() does not override the signal's ignore disposition. Applications relying on the older sigwait(2) behavior can break unless you install a dummy signal handler to change the disposition from SIG_IGN to having a handler, so calls to sigwait() for this signal catch it.
The syntax for the two versions of sigwait() is shown below.
#include <signal.h> /* the Solaris 2.5 version*/ int sigwait(sigset_t *set); /* the POSIX.1c version */ int sigwait(const sigset_t *set, int *sig);
When the signal is delivered, the POSIX.1c sigwait() clears the pending signal and places the signal number in sig. Many threads can call sigwait() at the same time, but only one thread returns for each signal that is received.
With sigwait() you can treat asynchronous signals synchronously--a thread that deals with such signals simply calls sigwait() and returns as soon as a signal arrives. By ensuring that all threads (including the caller of sigwait()) have such signals masked, you can be sure that signals are handled only by the intended handler and that they are handled safely.
By always masking all signals in all threads, and just calling sigwait() as necessary, your application will be much safer for threads that depend on signals.
Usually, you use sigwait() to create one or more threads that wait for signals. Because sigwait() can retrieve even masked signals, be sure to block the signals of interest in all other threads so they are not accidentally delivered.
When the signals arrive, a thread returns from sigwait(), handles the signal, and waits for more signals. The signal-handling thread is not restricted to using Async-Signal-Safe functions and can synchronize with other threads in the usual way. (The Async-Signal-Safe category is defined in "MT Interface Safety Levels".)