Estás en:   ArielOrtiz.com > Programación avanzada > Procesamiento de señales

Procesamiento de señales

En algunas ocasiones, los programas tienen que lidiar con eventos inesperados o impredecibles, tales como:

Este tipo de eventos se les conoce también como interrupciones, dado que deben interrumpir el flujo normal de un programa con el fin de ser procesados. Cuando el kernel de Linux detecta que ha ocurrido un cierto evento le manda al proceso correspondiente una señal. Hay un número de señal único asociado a cada evento posible.

El kernel no es el único que puede enviar señales. Un proceso le puede enviar a otro proceso una señal, siempre y cuando tenga los permisos adecuados.

En un programa es posible indicar que una señal en particular sea ignorada o sea procesada por una porción de código conocida como manejador de señal. En este último caso, el proceso que recibe la señal suspende su flujo actual de control, ejecuta el manejador de señal, y finalmente reanuda el flujo de control original.

API de C para procesar señales

signal

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

Establece handler como la forma de manejar la señal signum. handler puede ser SIG_IGN (ignorar), SIG_DFL (default), o la dirección de una función definida por el programador (un "manejador de señal").

Devuelve el valor anterior del manejador de señal, o SIG_ERR en caso de error.

alarm

#include <unistd.h>

unsigned int alarm(unsigned int sec);

Le indica al kernel que genere una señal SIGALRM al proceso invocador despues de sec segundos. Si ya había una alarma programada, ésta se sobre escribe. Si sec es 0, cualquier alarma pendiente se cancela.

Devuelve el número de segundos que quedan antes de que la señal de alarma se produzca.

pause

#include <unistd.h>

int pause(void);

Suspende el proceso invocador y regresa cuando éste recibe una señal. Es una forma eficiente de esperar una señal de alarma. No devuelve ningún valor útil.

sleep

#include <unistd.h>

unsigned int sleep(unsigned int sec);

Espera a que transcurran sec segundos o a que se reciba una señal, lo que ocurra primero. Si el intervalo de tiempo caducó, devuelve 0. Si se recibió una señal, devuelve el valor del tiempo restante.

Lista de señales

Esta es una lista de las señales predefinidas en Linux (tomada de [KERRISK] y [GLASS]).

ACTIONS

dump: terminate the process and generate a core (memory) image file.

quit: terminate the process without generating a core image file.

ignore: ignore and discard the signal.

suspend: suspends the process.

Name Signal
Number
Default Action Description
SIGHUP 1 quit When a terminal disconnect (hangup) occurs, this signal is sent to the controlling process of the terminal.
SIGINT 2 quit When the user types the terminal interrupt character (usually Ctrl-C), the terminal sends this signal to the foreground process.
SIGQUIT 3 dump When the user types the quit character (usually Ctrl-|) on the keyboard, this signal is sent to the foreground process. By default, this signal terminates a process and causes it to produce a core dump, which can then be used for debugging.
SIGILL 4 dump This signal is sent to a process if it tries to execute an illegal (i.e., incorrectly formed) machine-language instruction.
SIGTRAP 5 dump This signal is used to implement debugger breakpoints and system call tracing.
SIGABRT 6 dump A process is sent this signal when it calls the abort() function.
SIGBUS 7 dump This signal ("bus error") is generated to indicate certain kinds of memory-access errors.
SIGFPE 8 dump This signal is generated for certain types of arithmetic errors, such as divide-by-zero. The suffix FPE is an abbreviation for floating-point exception, although this signal can also be generated for integer arithmetic errors.
SIGKILL 9 quit This is the sure kill signal. It can't be blocked, ignored, or caught by a handler, and thus always terminates a process.
SIGUSR1 10 quit This signal and SIGUSR2 are available for programmer-defined purposes. The kernel never generates these signals for a process. Processes may use these signals to notify one another of events or to synchronize with each other.
SIGSEGV 11 dump This very popular signal is generated when a program makes an invalid memory reference. In C, these events often result from dereferencing a pointer containing a bad address (e.g., an uninitialized pointer) or passing an invalid argument in a function call. The name of this signal derives from the term "segmentation violation".
SIGUSR2 12 quit See the description of SIGUSR1.
SIGPIPE 13 quit This signal is generated when a process tries to write to a pipe for which there is no corresponding reader process.
SIGALRM 14 quit The kernel generates this signal upon the expiration of a real-time timer set by a call to alarm() or setitimer(). A real-time timer is one that counts according to wall clock time (i.e., the human notion of elapsed time).
SIGTERM 15 quit This is the standard signal used for terminating a process and is the default signal sent by the kill command.
SIGSTKFLT 16 ignore Documented as "stack fault on coprocessor". This signal is defined, but is unused on Linux.
SIGCHLD 17 ignore This signal is sent (by the kernel) to a parent process when one of its children terminates (either by calling exit() or as a result of being killed by a signal).
SIGCONT 18 ignore When sent to a stopped process, this signal causes the process to resume (i.e., to be rescheduled to run at some later time). When received by a process that is not currently stopped, this signal is ignored by default. A process may catch this signal, so that it carries out some action when it resumes.
SIGSTOP 19 suspend This is the sure stop signal. It can't be blocked, ignored, or caught by a handler; thus, it always stops a process.
SIGTSTP 20 suspend This is the job-control stop signal, sent to stop the foreground process when the user types the suspend character (usually Ctrl-Z) on the keyboard. The name of this signal derives from "terminal stop".
SIGTTIN 21 suspend When running under a job-control shell, the terminal sends this signal to a background process when it attempts to read from the terminal. This signal stops a process by default.
SIGTTOU 22 suspend This signal serves an analogous purpose to SIGTTIN, but for terminal output by background jobs.
SIGURG 23 ignore This signal is sent to a process to indicate the presence of out-of-band (also known as urgent) data on a socket.
SIGXCPU 24 quit This signal is sent to a process when it exceeds its CPU time resource limit.
SIGXFSZ 25 quit This signal is sent to a process if it attempts to increase the size of a file beyond the process' file size resource limit.
SIGVTALRM 26 quit The kernel generates this signal upon expiration of a virtual timer set by a call to setitimer(). A virtual timer is one that counts the user-mode CPU time used by a process.
SIGPROF 27 quit The kernel generates this signal upon the expiration of a profiling timer set by a call to setitimer(). A profiling timer is one that counts the CPU time used by a process. Unlike a virtual timer SIGVTALRM, a profiling timer counts CPU time used in both user mode and kernel mode.
SIGWINCH 28 ignore In a windowing environment, this signal is sent to the foreground process when the terminal window size changes. By installing a handler for this signal, programs such as vi and less can know to redraw their output after a change in window size.
SIGIO 29 quit Using the fcntl() system call, it is possible to arrange for this signal to be generated when an I/O event (e.g., input becoming available) occurs on certain types of open file descriptors, such as those for terminals and sockets.
SIGPWR 30 quit This is the power failure signal. On systems that have an uninterruptible power supply (UPS), it is possible to set up a daemon process that monitors the backup battery level in the event of a power failure. If the battery power is about to run out (after an extended power outage), then the monitoring process sends SIGPWR to the init process, which interprets this signal as a request to shut down the system in a quick and orderly fashion.
SIGSYS 31 dump This signal is generated if a process makes a "bad" system call. This means that the process executed an instruction that was interpreted as a system call trap, but the associated system call number was not valid.

Referencias

[GLASS]
Graham Glass & King Ables.
UNIX for Programmers and Users, 3rd Edition.
Prentice Hall, 2003.
ISBN: 0130465534.
[KERRISK]
Michael Kerrisk.
The Linux Programming Interface: A Linux and UNIX System Programming Handbook.
No Starch Press, 2010.
ISBN: 1593272200.