A veces me confunden un poco todas las señales que puede recibir un proceso. Según tengo entendido, un proceso tiene un controlador predeterminado (disposición de señal ) para cada una de estas señales, pero puede proporcionar su propio controlador llamando a sigaction()
.
Así que aquí está mi pregunta:¿qué hace que se envíe cada una de las señales? Me doy cuenta de que puede enviar señales manualmente a los procesos en ejecución a través de -s
parámetro para kill
, pero ¿cuáles son los naturales circunstancias bajo las cuales se envían estas señales? Por ejemplo, ¿cuándo SIGINT
ser enviado?
Además, ¿existen restricciones sobre qué señales se pueden manejar? Puede incluso SIGSEGV
¿se procesarán las señales y se devolverá el control a la aplicación?
Respuesta aceptada:
Además de los procesos que llaman a kill(2)
, algunas señales son enviadas por el núcleo (o, a veces, por el propio proceso) en diversas circunstancias:
- Los controladores de terminal envían señales correspondientes a varios eventos:
- Notificaciones de pulsación de tecla:
SIGINT
(Vuelva al bucle principal) en Ctrl +C ,SIGQUIT
(salga inmediatamente) en Ctrl + ,SIGTSTP
(suspender) en Ctrl +Z . Las claves se pueden cambiar con elstty
comando. SIGTTIN
ySIGTTOU
se envían cuando un proceso en segundo plano intenta leer o escribir en su terminal de control.SIGWINCH
se envía para indicar que el tamaño de la ventana del terminal ha cambiado.SIGHUP
se envía para señalar que el terminal ha desaparecido (históricamente porque su módem tenía h ung arriba , hoy en día generalmente porque ha cerrado la ventana del emulador de terminal).
- Notificaciones de pulsación de tecla:
- Algunas trampas de procesador pueden generar una señal. Los detalles dependen de la arquitectura y del sistema; aquí hay ejemplos típicos:
SIGBUS
para una memoria de acceso no alineada;SIGSEGV
para acceder a una página no asignada;SIGILL
por una instrucción ilegal (código de operación incorrecto);SIGFPE
para una instrucción de coma flotante con argumentos incorrectos (por ejemplo,sqrt(-1)
).
- Una serie de señales notifican al proceso de destino que se ha producido algún evento del sistema:
SIGALRM
notifica que un temporizador establecido por el proceso ha expirado. Los temporizadores se pueden configurar conalarm
,setitimer
y otros.SIGCHLD
notifica a un proceso que uno de sus hijos ha muerto.SIGPIPE
se genera cuando un proceso intenta escribir en una tubería cuando el extremo de lectura se ha cerrado (la idea es que si ejecutafoo | bar
ybar
salidas,foo
es asesinado por unSIGPIPE
).SIGPOLL
(también llamadoSIGIO
) notifica al proceso que ha ocurrido un evento encuestable. POSIX especifica eventos encuestables registrados a través deI_SETSIG
ioctl
. Muchos sistemas permiten eventos encuestables en cualquier descriptor de archivo, configurado a través deO_ASYNC
fcntl
bandera. Una señal relacionada esSIGURG
, que notifica datos urgentes en un dispositivo (registrado a través delI_SETSIG
ioctl
) o enchufe.- En algunos sistemas,
SIGPWR
se envía a todos los procesos cuando el UPS señala que un corte de energía es inminente.
Estas listas no son exhaustivas. Las señales estándar se definen en signal.h
.
La mayoría de las señales pueden ser capturadas y manejadas (o ignoradas) por la aplicación. Las únicas dos señales portátiles que no se pueden captar son SIGKILL
(simplemente muere) y STOP
(detener la ejecución).
SIGSEGV
(falla de segmentación) y su primo SIGBUS
(error de bus) puede detectarse, pero es una mala idea a menos que realmente sepa lo que está haciendo. Una aplicación común para detectarlos es imprimir un seguimiento de la pila u otra información de depuración. Una aplicación más avanzada es implementar algún tipo de gestión de memoria en proceso o atrapar instrucciones incorrectas en motores de máquinas virtuales.
Finalmente, permítanme mencionar algo que no es una señal. Cuando presiona Ctrl +D al comienzo de una línea en un programa que está leyendo la entrada de la terminal, esto le dice al programa que se llegó al final del archivo de entrada. Esto no es una señal:se transmite a través de la API de entrada/salida. Me gusta Ctrl +C y amigos, la clave se puede configurar con stty
.