signal handling with multiple threads

signal handling with multiple threads

Post by keith.mich » Wed, 23 Feb 2005 03:47:36

When I send a kill -HUP to a multithreaded process, which thread
processes the interrupt? I am concerned because the signal handler
takes out a lock which could be held by the interrupted thread. Do I
have to create a daemon thread and bind the signal handler to that
thread only? If I do this is it safe on a single CPU system?

Another approach is to just set a flag in the signal handler and let
the mainline code handle the event later; but even setting the flag
should be mutex-protected to ensure write coherency on some
architectures, so again I have a potential deadlock. There must be a
simple way to support signal handlers that need locks in a
multi-threaded application!


signal handling with multiple threads

Post by bart » Wed, 23 Feb 2005 15:18:43

The easiest way to deal with this problem is to use the
sigwait interface to wait for the arrival of the desired
signal in a separate thread; this avoids deadlock.

int sigwait(const sigset_t *set, int *sig);

The sigwait() function selects a signal in set that is pend-
ing on the calling thread (see thr_create(3C) and
pthread_create(3C).) If no signal in set is pending,
sigwait() blocks until a signal in set becomes pending. The
selected signal is cleared from the set of signals pending
on the calling thread and the number of the signal is
returned, or in the standard-conforming version (see stan-
dards(5)) placed in sig. The selection of a signal in set is
independent of the signal mask of the calling thread. This
means a thread can synchronously wait for signals that are
being blocked by the signal mask of the calling thread . To
ensure that only the caller receives the signals defined in
set, all threads should have signals in set masked including
the calling thread. If the set argument points to an invalid
address, the behavior is undefined and errno may be set to

- Bart


signal handling with multiple threads

Post by Roland Mai » Thu, 24 Feb 2005 05:18:07

That doesn't answer the question what the "normal" behaviour is... which
thread receives the signal by default ?



__ . . __
(o.\ \/ /.o) XXXX@XXXXX.COM
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 7950090
(;O/ \/ \O;)

signal handling with multiple threads

Post by roger.faul » Thu, 24 Feb 2005 08:07:03


It could be any thread in the application whose signal mask
doesn't block the signal in question.

But this doesn't matter since you can't safely grab a lock
in a signal handler anyway. All you can do is set a flag
(without benefit of a lock) that says a signal was received.

The OP needs to do the job right, with a dedicated signal-handling
thread that uses sigwait().

Roger Faulkner
Sun Microsystems

signal handling with multiple threads

Post by keith.mich » Thu, 24 Feb 2005 11:01:26

Thanks for the sage advice Roger. I found an example of sigwait at: #SECTION003240000000000000000

I will have to create a separate daemon thread just for signal
masking the signal for all other threads.

I am still curious about using signal handlers to set a flag "without
benefit of a lock": easy enough to do, but what about write coherency?
Without a mutex which has the "side effect" of voiding the cache
there's no guarantee if/when a thread will see the flag. Seems
difficult to write a deterministic program that way :-)

signal handling with multiple threads

Post by roger.faul » Thu, 24 Feb 2005 15:19:01 #SECTION003240000000000000000

Pretty good, but you should translate the example into pthread_*()
interfaces rather than the legacy thr_*() Solaris threads interfaces.


You are right, theoretically.
However, on all versions of Solaris in existence, the flag will
become visible within a short time (at least milliseconds).

In Solaris 10, you could use one of the atomic add functions.
See <atomic.h>.

In the future, there will be more atomic operations, including
memory barriers, to deal with more relaxed memory models that
may/will come along.

Roger Faulkner
Sun Microsystems

signal handling with multiple threads

Post by Casper H.S » Thu, 24 Feb 2005 17:36:28


The daemon thread can sleep waiting for a signal using sigwait
and then do a broadcast on a condition variable.

No need to handle the signal in a signal handler.

Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.