Re-entrance and thread safety has a little or nothing to do with this. Side effects, state and interruption of those functions are facts that matter.
asynchronous-safe function [GNU Pth]
A function is asynchronous-safe,
or asynchronous-signal safe, if it can be called safely and without
side effects from within a signal handler context. That is, it must be
able to be interrupted at any point to run linearly out of sequence
without causing an inconsistent state. It must also function properly
when global data might itself be in an inconsistent state. Some
asynchronous-safe operations are listed here:
- call the
signal()
function to reinstall a signal handler
- unconditionally modify a
volatile sig_atomic_t
variable (as
modification to this type is atomic)
- call the
_Exit()
function to
immediately terminate program execution
- invoke an asynchronous-safe
function, as specified by your implementation
Few functions are
portably asynchronous-safe. If a function performs any other
operations, it is probably not portably asynchronous-safe.
A rule of thumb is this - only signal some condition variable from signal handler (such as futex/pthread condition, wake up epoll loop etc.).
UPDATE:
As EmployedRussian suggested, even calling pthread_cond_signal
is a bad idea. I've checked the source code of the recent eglibc
and it has lock/unlock pair in there. Thus, introducing a possibility for a deadlock. This leaves us with few options to signal other threads:
- Using
eventfd
.
- Changing global atomic variable and hope that SA_RESTART is not set and other threads will check our atomic.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…