En los sistemas POSIX, las señales de terminación suelen tener el siguiente orden (según muchas páginas MAN y las especificaciones POSIX):
SIGTERM: solicite cortésmente que finalice el proceso. Terminará elegantemente, limpiando todos los recursos (archivos, sockets, procesos secundarios, etc.), eliminando archivos temporales, etc.
SIGQUIT - solicitud más contundente. Terminará sin gracia, aún limpiando recursos que absolutamente necesitan limpieza, pero tal vez no elimine archivos temporales, tal vez escriba información de depuración en alguna parte; en algunos sistemas también se escribirá un volcado del núcleo (independientemente de si la aplicación capta la señal o no).
SIGKILL - petición más contundente. Ni siquiera se le pide al proceso que haga nada, pero el sistema limpiará el proceso, le guste o no. Lo más probable es que se escriba un volcado de memoria.
¿Cómo encaja SIGINT en esa imagen? Un proceso CLI generalmente es terminado por SIGINT cuando el usuario presiona CRTL + C, sin embargo, un proceso en segundo plano también puede ser terminado por SIGINT usando la utilidad KILL. Lo que no puedo ver en las especificaciones o los archivos de encabezado es si SIGINT es más o menos contundente que SIGTERM o si existe alguna diferencia entre SIGINT y SIGTERM.
ACTUALIZAR:
La mejor descripción de las señales de terminación que encontré hasta ahora está en la documentación GNU LibC . Explica muy bien que existe una diferencia intencionada entre SIGTERM y SIGQUIT.
Dice sobre SIGTERM:
Es la forma normal de pedir cortésmente a un programa que termine.
Y dice sobre SIGQUIT:
[...] y produce un volcado del núcleo cuando finaliza el proceso, al igual que una señal de error de programa. Puede pensar en esto como una condición de error de programa "detectada" por el usuario. [...] Es mejor omitir ciertos tipos de limpieza al manejar SIGQUIT. Por ejemplo, si el programa crea archivos temporales, debería manejar las otras solicitudes de terminación borrando los archivos temporales. Pero es mejor que SIGQUIT no los elimine, para que el usuario pueda examinarlos junto con el volcado de memoria.
Y SIGHUP también se explica bastante bien. SIGHUP no es realmente una señal de terminación, solo significa que la "conexión" con el usuario se ha perdido, por lo que la aplicación no puede esperar que el usuario lea más salida (por ejemplo, salida stdout / stderr) y no hay entrada que esperar del usuario por más tiempo. Para la mayoría de las aplicaciones, eso significa que es mejor que salgan. En teoría, una aplicación también podría decidir que entra en modo demonio cuando se recibe un SIGHUP y ahora se ejecuta como un proceso en segundo plano, escribiendo la salida en un archivo de registro configurado. Para la mayoría de los demonios que ya se ejecutan en segundo plano, SIGHUP generalmente significa que deben volver a examinar sus archivos de configuración, por lo que los envía a los procesos en segundo plano después de editar los archivos de configuración.
Sin embargo, no hay una explicación útil de SIGINT en esta página, aparte de que es enviado por CRTL + C. ¿Hay alguna razón por la que uno maneje SIGINT de una manera diferente a SIGTERM? Si es así, ¿cuál sería la razón y cómo sería diferente el manejo?
sudo fuser -l
en el símbolo del sistema. Para mí esto trae a colación:HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS UNUSED
kill -l
obtener una lista de señales.Respuestas:
SIGTERM y SIGKILL están destinados a solicitudes de "terminar este proceso" de propósito general. SIGTERM (por defecto) y SIGKILL (siempre) causarán la terminación del proceso. SIGTERM puede ser detectado por el proceso (por ejemplo, para que pueda hacer su propia limpieza si así lo desea), o incluso ignorado por completo; pero SIGKILL no puede ser capturado ni ignorado.
SIGINT y SIGQUIT están diseñados específicamente para solicitudes del terminal: se pueden asignar caracteres de entrada particulares para generar estas señales (dependiendo de la configuración de control del terminal). La acción predeterminada para SIGINT es el mismo tipo de terminación de proceso que la acción predeterminada para SIGTERM y la acción inmutable para SIGKILL; la acción predeterminada para SIGQUIT es también la terminación del proceso, pero pueden ocurrir acciones adicionales definidas por la implementación, como la generación de un volcado de memoria. Cualquiera puede ser detectado o ignorado por el proceso si es necesario.
SIGHUP, como usted dice, está destinado a indicar que la conexión del terminal se ha perdido, en lugar de ser una señal de terminación como tal. Pero, nuevamente, la acción predeterminada para SIGHUP (si el proceso no lo detecta o lo ignora) es terminar el proceso de la misma manera que SIGTERM, etc.
Hay una tabla en las definiciones POSIX para la
signal.h
que se enumeran las diversas señales y sus acciones y propósitos predeterminados, y el capítulo Interfaz de terminal general incluye muchos más detalles sobre las señales relacionadas con el terminal.fuente
Como señaló DarkDust, muchas señales tienen los mismos resultados, pero los procesos pueden asociarles diferentes acciones al distinguir cómo se genera cada señal. Mirando el código fuente del kernel de FreeBSD (kern_sig.c) veo que las dos señales se manejan de la misma manera, terminan el proceso y se envían a cualquier hilo.
fuente
man 7 signal
Esta es la conveniente página de manual no normativa del proyecto de páginas de manual de Linux que a menudo desea consultar para obtener información sobre señales de Linux.
La versión 3.22 menciona cosas interesantes como:
y contiene la tabla:
que resume la señal
Action
que distingue, por ejemplo, SIGQUIT de SIGQUIT, ya que SIGQUIT tiene acciónCore
y SIGINTTerm
.Las acciones están documentadas en el mismo documento:
No puedo ver ninguna diferencia entre SIGTERM y SIGINT desde el punto de vista del kernel ya que ambos tienen acción
Term
y ambos pueden ser capturados. Parece que es solo una "distinción de convención de uso común":kill
Algunas señales son ANSI C y otras no
Una diferencia considerable es que:
Se describen en el apartado "7.14 Manejo de señales" del borrador C99 N1256 :
lo que hace que SIGINT sea un buen candidato para un Ctrl + C interactivo.
POSIX 7
POSIX 7 documenta las señales con el
signal.h
encabezado: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.htmlEsta página también tiene la siguiente tabla de interés que menciona algunas de las cosas que ya habíamos visto
man 7 signal
:BusyBox init
El comando predeterminado 1.29.2 de BusyBox
reboot
envía un SIGTERM a los procesos, duerme por un segundo y luego envía SIGKILL. Esta parece ser una convención común en diferentes distribuciones.Cuando apaga un sistema BusyBox con:
envía una señal al proceso de inicio.
Entonces, el manejador de señales init termina llamando:
que imprime en la terminal:
Aquí hay un ejemplo concreto mínimo de eso .
Señales enviadas por el kernel
fuente
Después de una búsqueda rápida en Google de sigint vs sigterm , parece que la única diferencia intencionada entre los dos es si se inició mediante un método abreviado de teclado o mediante una llamada explícita a
kill
.Como resultado, podría, por ejemplo, interceptar sigint y hacer algo especial con él, sabiendo que probablemente fue enviado por un atajo de teclado. Quizás actualice la pantalla o algo, en lugar de morir (no recomendado, ya que la gente espera
^C
matar el programa, solo un ejemplo).También aprendí que
^\
debería enviar sigquit, que puedo comenzar a usar yo mismo. Parece muy útil.fuente
Usando
kill
(tanto la llamada al sistema como la utilidad`, puede enviar casi cualquier señal a cualquier proceso, siempre que tenga el permiso. Un proceso no puede distinguir cómo una señal cobró vida y quién la envió.Dicho esto, SIGINT realmente está destinado a señalar la interrupción Ctrl-C, mientras que SIGTERM es la señal de terminal general. No existe el concepto de que una señal sea "más contundente", con la única excepción de que hay señales que no se pueden bloquear ni manejar (SIGKILL y SIGSTOP, según la página de manual).
Una señal solo puede ser "más contundente" que otra señal con respecto a cómo un proceso de recepción maneja la señal (y cuál es la acción predeterminada para esa señal). Por ejemplo, de forma predeterminada, tanto SIGTERM como SIGINT conducen a la terminación. Pero si ignora SIGTERM, no terminará su proceso, mientras que SIGINT todavía lo hace.
fuente
Con la excepción de algunas señales, los manejadores de señales pueden captar las diversas señales, o se puede modificar el comportamiento predeterminado al recibir una señal. Consulte la
signal(7)
página del manual para obtener más detalles.fuente
SIGINT
señal (“ interrupción del programa ”) se envía cuando el usuario escribe el carácter INTR (normalmenteC-c
)". "SIGINT 2 Term Interrupt from keyboard" Presiona Ctrl-C,SIGINT
se envía. El proceso normalmente muere. ¿Qué más dar?