Signals
- Signals are mechanisms for communicating with and manipulating processes.
- A signal is a special message sent to a process.
- Signals are asynchronous; when a process receives a signal, it processes the signal immediately, without finishing the current function or even the current line of code.
- Each signal type is specified by its signal number, but in programs, you usually refer to a signal by its name. (In Linux, these are defined in /usr/include/bits/signum.h)
- When a process receives a signal, it may do one of several things, depending on the signal's disposition.
- For each signal, there is a default disposition, which determines what happens to the process if the program does not specify some other behavior.
- For most signal types, a program may specify some other behavior-either to ignore the signal or to call a special signal-handler function to respond to the signal.
- If a signal handler is used, the currently executing program is paused, the signal handler is executed, and, when the signal handler returns, the program resumes.
- The system sends signals to processes in response to specific conditions.
- For instance, SIGBUS (bus error), SIGSEGV (segmentation violation), and SIGFPE (floating point exception) may be sent to a process that attempts to perform an illegal operation.
- The default disposition for these signals it to terminate the process and produce a core file.
- A process may also send a signal to another process.
- One common use of this mechanism is to end another process by sending it a SIGTERM or SIGKILL signal.
- Another common use is to send a command to a running program.Two "userdefined" signals are reserved for this purpose: SIGUSR1 and SIGUSR2.
- The SIGHUP signal is sometimes used for this purpose as well, commonly to wake up an idling program or cause a program to reread its configuration files.
- The sigaction function can be used to set a signal disposition.
- The first parameter is the signal number. The next two parameters are pointers to sigaction structures; the first of these contains the desired disposition for that signal number, while the second receives the previous disposition.
- The most important field in the first or second sigaction structure is sa_handler. It can take one of three values:
- SIG_DFL, which specifies the default disposition for the signal.
- SIG_IGN, which specifies that the signal should be ignored.
- A pointer to a signal-handler function.The function should take one parameter,
the signal number, and return void.
- A signal handler should perform the minimum work necessary to respond to the signal, and then return control to the main program (or terminate the program).
- The main program then checks periodically whether a signal has occurred and reacts accordingly.
- It is possible for a signal handler to be interrupted by the delivery of another signal.
- Even assigning a value to a global variable can be dangerous because the assignment may actually be carried out in two or more machine instructions, and a second signal may occur between them, leaving the variable in a corrupted state.
- If you use a global variable to flag a signal from a signal-handler function, it should be of the special type sig_atomic_t.
- The following program skeleton, for instance, uses a signal-handler function to
count the number of times that the program receives SIGUSR1, one of the signals
reserved for application use.
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
sig_atomic_t sigusr1_count = 0;
void handler (int signal_number)
{
++sigusr1_count;
}
int main ()
{
struct sigaction sa;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &handler;
sigaction (SIGUSR1, &sa, NULL);
/* Do some lengthy stuff here. */
/* ... */
printf ("SIGUSR1 was raised %d times\n", sigusr1_count);
return 0;
}
2006-03-17