Systems Programming

Signals

Signals are a simple way to communicate a very small amount of information to a process. For example, a signal can be used to tell a process that you would like it to terminate. Or a process might get a signal that tells it an alarm it had set has expired. The main feature of signals is that they are asynchronous, which means that they can happen at any time and may interrupt a process's normal control flow. Unix signals are a software analog to interrupts in the hardware world (in fact, Unix-like systems convert hardware interrupts to signals, which is important for device drivers). They may seem like Java exceptions, but they are much heavier weight, considerably less flexible, and much more restrictive.

Nonetheless, signals are a fact of life for almost any significant application, particularly one that must run for a long time and handle interactions among multiple processes (or threads).

All signals are defined by a positive number (there is no signal 0), and each one has a name that begins with SIG. SIGINT is the INTerrupt signal sent to a process when you type C-c at the shell. The kernel sends your process the SIGFPE to indicate a floating point error. A process gets a SIGCHILD when one of its children terminates. You have all experienced the SIGSEGV signal, which is sent to a process that has attempted to perform an invalid memory access. There are fairly small number of possible signals (e.g., Linux defines 30 different signals).

A process can only send another process a signal if its effective user ID is either root or the owner of the intended signal recipient.

A signal can be generated either naturally when certain situations arise (like errors or the termination of a child process) or deliberately via the use of a system call (e.g., when a process calls abort()).

You can send a process a signal form the shell using the kill command, which is really a wrapper for the kill() system call:

int kill(pid_t pid, int sig);
The arguments are the ID of the process to which you would like to send the signal, and sig is the signal you would like to send. You can also send a signal to every member of a process group. The return value is 0 on success or -1 on error (and errno is set). kill() can fail, for example, if there is no such process or process group or if you do have have permission to send a message to the recipient.

A process or thread can send a signal to itself using


Author: Mark A. Sheldon
Modified: 28 March 2007