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() might 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 beginning with the Solaris Operating Environment 2.5 release: the new Solaris Operating Environment 2.5 version, and the POSIX.1c version. New applications and libraries should use the POSIX standard interface, as the Solaris Operating Environment version might not be available in future releases.
The new Solaris Operating Environment 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".)