3.2.2. Linux: señales POSIX
Material de estudio basado en la edición de 2014. Borrador pendiente de revisión editorial independiente.
Linux: Señales POSIX
Resumen
La interfaz POSIX de señales (también llamada reliable signals) es la más completa y robusta. Es la utilizada por Linux.
Terminología
| Término | Definición |
|---|---|
| Generación | Momento en que se produce la señal |
| Tratamiento | Rutina de atención para una señal (defecto del SO o usuario) |
| Depósito | Momento en que se empieza a ejecutar la rutina de tratamiento |
| Señal pendiente | Señal generada pero aún no depositada |
| Programación | Asociar un tratamiento a una señal |
| Captura | Ejecución de la rutina de usuario para atender la señal |
| Señal bloqueada | El SO no deposita señales de este tipo mientras estén bloqueadas |
| Señal ignorada | El SO descarta las señales de este tipo |
Lista de señales POSIX (principales)
| Señal | Significado | Tratamiento por defecto |
|---|---|---|
| SIGHUP | Corte de línea de comunicación | EXIT |
| SIGINT | Tecla de control (Ctrl-C) | EXIT |
| SIGABRT | Abortar ejecución | EXIT + CORE |
| SIGFPE | Excepción de coma flotante | EXIT + CORE |
| SIGKILL | Destruir proceso (no se puede ignorar/bloquear) | EXIT |
| SIGSEGV | Acceso indebido a memoria | EXIT + CORE |
| SIGPIPE | Escritura en pipe sin lector | EXIT |
| SIGALRM | Expiración de temporizador | EXIT |
| SIGTERM | Solicitud de fin de proceso | EXIT |
| SIGUSR1/SIGUSR2 | Para uso de aplicaciones | EXIT |
| SIGCHLD | Muerte de proceso hijo | IGNORE |
| SIGSTOP | Detener proceso (Ctrl-Z, no reprogramable) | STOP |
| SIGCONT | Reanudar proceso detenido | CONT |
Conjuntos de señales (sigset_t)
POSIX ofrece un tipo sigset_t y funciones para manipularlo:
int sigemptyset(sigset_t *set); /* Conjunto vacío */
int sigfillset(sigset_t *set); /* Todos los signals */
int sigaddset(sigset_t *set, int signum); /* Añadir signal */
int sigdelset(sigset_t *set, int signum); /* Eliminar signal */
int sigismember(const sigset_t *set, int signum); /* ¿Pertenece? */
Programación de señales (sigaction)
struct sigaction {
void (*sa_handler)(int); /* Rutina de atención */
sigset_t sa_mask; /* Señales bloqueadas durante la rutina */
int sa_flags; /* Modificar comportamiento POSIX */
};
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
sa_handler: rutina a ejecutar,SIG_IGNpara ignorar,SIG_DFLpara defecto.sa_mask: señales bloqueadas mientras se ejecuta la rutina de atención.sa_flags = 0para comportamiento POSIX estándar.- La programación es válida hasta que se vuelva a programar la misma señal.
- En
fork, el hijo hereda la programación. Enexec, todas recuperan la programación por defecto excepto las marcadas comoSIG_IGN.
Generación de señales
int kill(pid_t pid, int sig); /* Genera señal "inmediatamente" */
unsigned int alarm(unsigned int seconds); /* Temporizador → SIGALRM */
kill: genera una señal sobre un proceso. Error si pertenece a otro usuario o no existe.alarm: programa un temporizador. Al expirar, generaSIGALRM. Con parameter 0, cancela el temporizador.
Conjunto de señales bloqueadas (sigprocmask)
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
SIG_BLOCK: añade señales al conjunto bloqueado.SIG_UNBLOCK: elimina señales del conjunto bloqueado.SIG_SETMASK: asigna directamente el conjunto.
Se hereda en fork y se mantiene en exec. Si se modifica dentro de una rutina de atención, el SO restaura el valor previo al acabar.
Errores frecuentes: usar SIG_SETMASK sin considerar las señales ya bloqueadas. La opción correcta es bloquear temporalmente, usar, y restaurar el valor anterior.
Espera de señales (sigsuspend)
int sigsuspend(const sigset_t *mask);
Realiza atómicamente:
- Asigna
maskcomo nuevo conjunto de señales bloqueadas. - Bloquea el proceso hasta que se deposite una señal no bloqueada.
Al depositar la señal, ejecuta el tratamiento, restaura el valor previo del conjunto bloqueado y el proceso continúa.
Problema con pause: puede haber una carrera entre verificar una variable y llamar a pause, perdiéndose la señal. sigsuspend resuelve esto ejecutando las dos operaciones de manera atómica.
Depósito sobre procesos bloqueados
Cuando un proceso está bloqueado (leyendo de pipe vacía, en sem_wait, etc.) y recibe una señal:
- Si el tratamiento no mata al proceso, el SO puede:
- Abortar la llamada al sistema (devuelve -1 con
errno = EINTR). - Reiniciar la llamada al sistema (el proceso se vuelve a bloquear).
- Abortar la llamada al sistema (devuelve -1 con
Depende del tipo de llamada y de sa_flags. Se recomienda control exhaustivo de errores.
Ideas clave
- POSIX es la interfaz de señales más completa y fiable para Linux.
sigactionpermite definir rutinas de atención con máscara de bloqueo temporal.sigprocmaskgestiona el conjunto de señales bloqueadas del proceso.sigsuspendresuelve la carrera entre verificación y espera de forma atómica.- Las señales en procesos bloqueados pueden abortar o reiniciar la llamada al sistema.
- No se puede reprogramar SIGKILL ni SIGSTOP.