I have a process p
registered with a signal handler for SIGALRM
. A timer is setup to periodically send signal SIGALRM
to process p
. There are also multiple threads running in process p
. Is the signal handler, when being triggered and executed, un-preemptible? Or to say, is it that the execution of signal handler will not be interrupted by any thread in process p
?
PS: I thought signal handler is executed in kernel (is it?) and kernel is unpreemptive to user-mode threads? Correct me if it's wrong...
The kernel process then uses the signal number to determine which action should be taken. The kernel does not automatically call signal handlers for a kernel process as it does for user processes.
Signal handlers usually execute on the current stack of the process. This lets the signal handler return to the point that execution was interrupted in the process. This can be changed on a per-signal basis so that a signal handler executes on a special stack.
Signal Handlers. A signal handler is special function (defined in the software program code and registered with the kernel) that gets executed when a particular signal arrives. This causes the interruption of current executing process and all the current registers are also saved.
Signal handlers can be interrupted by signals, including their own. If a signal is not reset before its handler is called, the handler can interrupt its own execution. A handler that always successfully executes its code despite interrupting itself or being interrupted is async-signal-safe.
Pretty much - don't - dealing with shared data in a signal handler almost always leads to a world of pain, dealing with threads as well and you got yourself a mess.
By default a signal is blocked while the signal handler is running (at least on linux, that might not be universally true), so at least the signal handler will not be preempted by itself. Though, if you have multiple threads, and the signal is not blocked in the other threads, a signal handler might very well be run concurrently within several threads.
One thread will receive the signal and execute the handler, it's more or less random which thread that'll be, although you could control it by blocking the signal in all threads you don't want to handle the signal.
However, any of the other threads bar the one handling the signal might run in parallell. The thread handling a signal could run the signal handler at pretty much any point in the program (as long as the signal isn't blocked.) So, you'd need some sort of locking to protect that data. The problem is you can't use any of the normal thread locking primitives, they are not signal async safe. Meaning if you e.g. try to grab a pthread_mutex_t in a signal handler, you easily deadlock your program.
The only functions you can safely call in a signal handler are the ones listed here . With regards to protecting the shared data, you could use sigblock()/sigunblock() as a sort of protection, ensuring the signal handler doesn't run while you're accessing that shared data - and the signal have to blocked in all the threads, otherwise it'll just run within one of the threads that doesn't have it blocked - going down that road is madness.
Pretty much the only shared data you can safely access in a signal handler is a sig_atomic_t
type, in practice other kinds of primitive types usually safe too.
What you really should do in a signal handler is just
Or
Or
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With