All about Linux signals

Signals and threads


There are differences in signal handling between a single-threaded program and a multi-threaded program. Since according to POSIX specification a multi-threaded program is one process with one PID, which thread is interrupted to handle the arriving signal? If you use the old (unsupported) LinuxThreads implementation the answer is simple: all threads have separate PIDs, so the signal is delivered to the thread with PID provided to kill(2), so in case of this implementation all threads are treated as separate processes. This fact is not really interesting since this implementation is not used in any modern Linux distribution.

With Native POSIX Threads Library things get more interesting. Since this is the POSIX compliant implementation the behavior described here also applies to other POSIX systems.

Which thread receives the signal?


This is the most interesting question. There are two cases:
  • Process-directed signals (sent to a PID using functions like kill(2)). Threads have their separate signal mask which can be manipulated using pthread_sigmask(2) similary to sigprocmask(2), so such signal is not delivered to a thread that has this signal blocked. It's delivered to one of threads in the process with this signal unblocked. It's unspecified which thread will get it. If all threads have the signal blocked, it's queued in the per-process queue. If there is no signal handler defined for the signal and the default action is to terminate the process with or without dumping the core the whole process is terminated.
  • Thread-directed signals. There is a special function to send a signal to a specific thread: pthread_kill(2). It can be used to send a signal from one thread to another (or itself). This way the signal will be delivered or queued for the specific thread. There are also per-thread directed signals generated by the operating system like SIGSEGV. If there is no signal handler defined for a signal that default's action is to terminate the process, a thread-directed signal terminated the whole process.

As you can see there is a process-wide signal queue and a per-thread queues.

Signal handlers


Signal actions are set for the whole process. The behavior of signal(2) is undefined for multi-threaded application, sigaction(2) must be used. Keep in mind that none of pthreads related functions are described as signal safe in signal(7). Especially using mutexes in signal handlers is very bad idea.

sigwaitinfo()/sigtimedwait() and process-directed signals


To get sigwaitinfo(2) and sigtimedwait(2) functions behave reliable for process-directed signals, all signals you wait for must be blocked for all threads. Especially using pause() for process-directed signals can be a bad idea.

Real-time signals


As previously said, both threading implementations (LinuxThreads and NPTL) internally use some number of real-time signals, so it's another good reason to always refer to those signals using SIGRTMIN+n notation.

Hi, typo jerk here

Hi, typo jerk here again: page3: Moreover, it lack's features -> lacks why the signal was send -> sent page5: signals like SIGPIPE, SIGUSR1, SIGUSR1 -> SIGUSR2 signal i exits -> it This program read from it's -> reads, its Additionally when SIGUSR1 -> Additionally, when [missing comma] I hope you really, truly don't consider this as some kind of personal attack.

Thanks. I don't consider it

Thanks. I don't consider it as an attack :) Some of them are just caused by the fact that English is not my native language.

I was looking for linux

I was looking for linux programming tutorial and i found this blog . keep good work.

Great write-up

Great write-up; thanks for the information.

Signals - That's not everything

I wouls suggest the reading of "Advanced Programming in the Unix Environment". It does not address signals with threads, but it is the most extensive explanation of signal handling. It treats also long jumps to remove races in signal handling.