Signals are a way of sending simple messages to processes. Most of these
messages are already defined and can be found in <linux/signal.h>.
However, signals can only be processed when the process is in user mode.
If a signal has been sent to a
process that is in kernel mode, it is dealt with immediately on
returning to user mode.
Signals are one of the oldest inter-process communication methods used by
Unix TM systems.
They are used to signal asynchronous events to one or more processes.
A signal could be generated by a keyboard interrupt or an error condition such as the
process attempting to access a non-existent location in its virtual memory.
Signals are also used by the shells to signal job control commands to their child processes.
There are a set of defined signals that the kernel can generate or that can be
generated by other processes in the system, provided that they have the correct
You can list a system's set of signals using the kill command (kill -l), on my Intel
Linux box this gives:
| 1) SIGHUP|| 2) SIGINT|| 3) SIGQUIT|| 4) SIGILL
| 5) SIGTRA|| 6) SIGIOT|| 7) SIGBUS|| 8) SIGFPE
| 9) SIGKILL||10) SIGUSR1||11) SIGSEGV||12) SIGUSR2
|13) SIGPIPE||14) SIGALRM||15) SIGTERM||17) SIGCHLD
|18) SIGCONT||19) SIGSTOP||20) SIGTSTP||21) SIGTTIN
|22) SIGTTOU||23) SIGURG||24) SIGXCPU||25) SIGXFSZ
|26) SIGVTALRM||27) SIGPROF||28) SIGWINCH||29) SIGIO
The numbers are different for an Alpha AXP Linux box.
Processes can choose to ignore most of the signals that are generated, with two notable
exceptions: neither the SIGSTOP signal which causes
a process to halt its execution nor the SIGKILL signal which causes a process to
exit can be ignored.
Otherwise though, a process can choose just how it wants to handle the various signals.
Processes can block the signals and, if they do not block them, processes can either choose
to handle the signals themselves or allow the kernel to handle them.
If the kernel handles the signals, it will do the default actions required for this
For example, the default action when a process receives the SIGFPE (floating point
exception) signal is to core dump and then exit. Signals have no inherent relative
priorities. If two signals are generated for a process at the same time then they may be
presented to the process or handled in any order.
Also there is no mechanism for handling multiple signals of the same kind.
There is no way that a process can tell if it received 1 or 42 SIGCONT signals.
Linux implements signals using information stored in the task_struct for the
process. The number of supported signals is limited to the word size of the processor.
Processes with a word size of 32 bits can have 32 signals whereas 64 bit processors like
the Alpha AXP may have up to 64 signals.
The currently pending signals are kept in the signal field with a mask of blocked
signals held in blocked.
With the exception of SIGSTOP and SIGKILL, all signals can be blocked.
If a blocked signal is generated, it remains pending until it is unblocked.
Linux also holds information about how each process handles every possible signal and this
is held in an array of sigaction data structures pointed at by the task_struct
for each process.
Amongst other things it contains either the address of a routine that will handle
the signal or a flag which tells Linux that the process either wishes to ignore this
signal or let the kernel handle the signal for it.
The process modifies the default signal handling by making system calls and these calls
alter the sigaction for the appropriate signal as well as the blocked mask.
Not every process in the system can send signals to every other process. For
security reason (among other things) only the
kernel can and super users can send signals to all processes.
Normal processes can only send signals to processes with the same uid and gid or
to processes in the same process group.
Signals are generated by setting the appropriate bit in the task_struct's signal
If the process has not blocked the signal and is
waiting but interruptible (in state Interruptible) then it is woken up
by changing its state to Running and making sure that it is in the run queue.
That way the scheduler will consider it a candidate for running when the system next
If the default handling is needed, then Linux can optimize the handling of the signal.
For example if the signal SIGWINCH (the X window changed focus) and the
default handler is being used then there is nothing to be done.
Signals are not presented to the process immediately after they are generated. Instead, they
must wait until the process is running again.
Every time a process exits from a system call, its signal and blocked fields
are checked and, if there are any unblocked signals, they can now be delivered.
This might seem a very unreliable method since it is dependant on the processes checking the signals,
but every process in the system is making
system calls, for example to write a character to the terminal, all of the time.
Processes can elect to wait for signals if they wish, they are suspended in
state Interruptible until a signal is presented.
The Linux signal processing code looks at the sigaction structure for each of
the current unblocked signals.
If a signal's handler is set to the default action, then the kernel will handle
it. The SIGSTOP signal's default handler will change the current process' state
to Stopped, then run the scheduler to select a new process to run. The default
action for the SIGFPE signal core dumps the process and then causes it to exit.
Alternatively, a process may have specfied its own signal handler. This is a
routine that is called whenever the signal is generated and the sigaction
structure holds the routine's address. It is the kernel's job to call the
process' signal handling routine. How this happens is processor specific but all
CPUs must cope with the fact that the current process that has been running in
kernel mode is just about to return to the calling process in user mode. The
problem is solved by doing several things such as manipulating the process'
stack and registers, resetting the process' program counter to the address of
its signal handling routine and either adding the parameters of the routine to
the call frame or passing in registers. Whatever the CPU's exact mechanism, when
the process resumes operation it appears as if the signal handling routine had
been called normally.
Linux is POSIX compatible and so the process can specify which signals are blocked
when a particular signal handling routine is called.
This entails changing the blocked mask during the call to the processes signal handler.
The blocked mask must be returned to its original value when the signal handling
routine has finished.
Therefore Linux adds a call to a tidy up routine that will restore the original
blocked mask onto the call stack of the signalled process.
Linux also optimizes the case where several signal handling routines need to be called
by stacking them so that each time one handling routine exits, the next one is called
until the tidy up routine is called.
Many signals (such as signal 9, SIGKILL), have the ability to
immediately terminate a process. However, most of these signals can be either
ignored or dealt with by the process itself. If not, the kernel
will take the default action specified for that signal.
You can send signals to processes yourself by means of the kill command,
as well as by the Delete key and Ctrl+/. However, you can only send
signals to processes that you own unless you are root. If you are root, you can send
signals to any process.
It's possible that the process to which you want to send the signal
is sleeping. If that process is sleeping at an interruptible priority, then the
process will awaken to handle the signal.
The kernel keeps track of pending signals in each process'
process structure. This is a 32-bit value in which each bit represents a single
signal. Because it is only one bit per
signal, there can only be one signal pending of each type. If
there are different kinds of signals pending, the kernel
has no way of determining which came in when. It will therefore process the signals
starting at the lowest numbered signal and moving up.