2010-10-28 13 views
77

En sistemas POSIX, señales de terminación por lo general tienen el siguiente orden (de acuerdo con muchas páginas de manual y el Spec POSIX):¿Cómo se relaciona SIGINT con las otras señales de terminación?

  1. SIGTERM - cortésmente pedir a un proceso para terminar. Terminará correctamente, limpiando todos los recursos (archivos, sockets, procesos secundarios, etc.), eliminando archivos temporales, etc.

  2. SIGQUIT - solicitud más enérgica. Terminará sin gracia, sigue limpiando los recursos que absolutamente necesitan limpieza, pero tal vez no elimine los archivos temporales, tal vez escriba información de depuración en alguna parte; en algún sistema también se escribirá un volcado del núcleo (independientemente de si la señal es capturada por la aplicación o no).

  3. SIGKILL - petición más enérgica. El proceso ni siquiera se pide que haga nada, pero el sistema limpiará el proceso, ya sea que así sea o no. Lo más probable es que se escriba un volcado del núcleo.

¿Cómo encaja SIGINT en esa imagen? Un proceso CLI usualmente es terminado por SIGINT cuando el usuario golpea CRTL + C, sin embargo, un proceso de fondo también puede ser terminado por SIGINT usando la utilidad KILL. Lo que no puedo ver en las especificaciones o en los archivos de encabezado es si SIGINT es más o menos enérgico que SIGTERM o si hay alguna diferencia entre SIGINT y SIGTERM en absoluto.

ACTUALIZACIÓN:

La mejor descripción de señales de terminación he encontrado hasta ahora es en el GNU LibC Documentation. Explica muy bien que existe una diferencia intencionada entre SIGTERM y SIGQUIT.

que dice acerca de SIGTERM:

Es la forma normal de pedir educadamente un programa para terminar.

Y que dice acerca de SIGQUIT:

[...] y produce un volcado de memoria cuando se termina el proceso, al igual que una señal de error del programa. Puede considerar esto como una condición de error del programa "detectada" por el usuario. [...] Ciertos tipos de limpiezas se omiten mejor al manejar SIGQUIT. Por ejemplo, si el programa crea archivos temporales, debe manejar las otras solicitudes de terminación eliminando los archivos temporales . Pero es mejor para SIGQUIT no eliminarlos, para que el usuario pueda examinarlos en junto con el volcado del núcleo.

Y SIGHUP también se explica lo suficiente. SIGHUP no es realmente una señal de terminación, solo significa que la "conexión" al usuario se ha perdido, por lo que la aplicación no puede esperar que el usuario lea ningún resultado adicional (por ejemplo, la salida stdout/stderr) y no hay información que esperar de la usuario por más tiempo Para la mayoría de las aplicaciones eso significa que es mejor dejarlo. En teoría, una aplicación también podría decidir que entra en modo daemon cuando se recibe un SIGHUP y ahora se ejecuta como un proceso en segundo plano, escribiendo salida en un archivo de registro configurado. Para la mayoría de los daemons que ya se ejecutan en segundo plano, SIGHUP generalmente significa que deben volver a examinar sus archivos de configuración, por lo que lo envía a 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, salvo que se envía por CRTL + C. ¿Hay alguna razón por la cual uno manejaría SIGINT de una manera diferente que SIGTERM? Si es así, ¿qué razón sería esto y cómo sería el manejo diferente?

+1

Buena pregunta. Sospecho que parte de la cruzada histórica de Unix estaría involucrada en la respuesta. –

+0

Sé que esta pregunta es antigua, pero en caso de que alguien venga aquí para obtener una lista exhaustiva de señales para su sistema operativo (Linux), se pueden encontrar escribiendo 'sudo fuser -l' en el símbolo del sistema. Para mí esto trae a colación: 'HUP INT SALIR 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 ' –

+1

También intenta' kill -l' para una lista de señales. – AAAfarmclub

Respuesta

58

SIGTERM y SIGKILL están destinados a fines generales de "finalización de este proceso" de solicitudes. SIGTERM (de forma predeterminada) y SIGKILL (siempre) provocarán la finalización del proceso. SIGTERM puede ser capturado por el proceso (por ejemplo, para que pueda hacer su propia limpieza si lo desea), o incluso ignorarlo por completo; pero SIGKILL no puede ser atrapado o 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 del control del terminal). La acción predeterminada para SIGINT es el mismo tipo de finalización del proceso que la acción predeterminada para SIGTERM y la acción inmutable para SIGKILL; la acción predeterminada para SIGQUIT también es la terminación del proceso, pero pueden ocurrir acciones adicionales definidas por la implementación, como la generación de un volcado del núcleo. Cualquiera puede ser atrapado 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, de nuevo, la acción predeterminada para SIGHUP (si el proceso no detecta o ignora) es terminar el proceso de la misma manera que SIGTERM, etc.

Hay una mesa en las definiciones para POSIXsignal.h que enumera las diversas señales y sus acciones y efectos predeterminados, y el capítulo General Terminal Interface incluye muchos más detalles sobre las señales relacionadas con terminal.

+8

Este es el punto clave: SIGINT y SIGQUIT se pueden generar desde el terminal usando caracteres únicos, mientras el programa se está ejecutando. Las otras señales tienen que ser generadas por otro programa, de alguna manera (por ejemplo, mediante el comando kill). SIGINT es menos violento que SIGQUIT; este último produce un volcado de núcleo. SIGKILL no puede ser atrapado. SIGHUP se genera si su conexión se cuelga (la ventana se cierra, etc.). Entonces, todos tienen diferentes significados. –

+0

[TTY Desmitificado] (http://www.linusakesson.net/programming/tty/index.php) tiene información fácilmente digerible sobre cómo las señales interactúan con el subsistema tty del kernel. Agrega un contexto a tu respuesta. –

+0

Parece que las especificaciones no son muy precisas, pero tengo entendido que SIgint le pide al programa que detenga su acción actual, no necesariamente abandone.Para un programa solo diseñado, realice una acción por ejecución que implique dejarlo, pero para un programa interactivo que tenga algún tipo de ciclo read-eval-print, puede significar renunciar a la evaluación actual y volver a leer la entrada del usuario. Creo que menos hace eso en Sigint. – bdsl

0

Con la excepción de algunas señales, los manejadores de señal pueden captar las diversas señales, o se puede modificar el comportamiento predeterminado al recibir una señal. Consulte la página del manual signal(7) para obtener más detalles.

+0

Sí, pero si no sé "el significado" de un singnal, captar la señal no tiene sentido, porque no sabré qué hacer en mi aplicación. GNU C p. explica la diferencia entre SIGQUIT y SIGTERM. Pero da poca información sobre SIGINT: http://www.gnu.org/s/libc/manual/html_node/Termination-Signals.html – Mecki

+0

"La señal' SIGINT' ("interrupción del programa") se envía cuando el usuario escribe el carácter INTR (normalmente 'Cc')." "Interrumpir el término SIGINT 2 desde el teclado" Se presiona Ctrl-C, se envía 'SIGINT'. El proceso normalmente muere. ¿Qué más dar? –

+0

Potencialmente podría haber una descripción de la intención que el programador debería asumir que tendrá el usuario cuando pulse ctrl-c, es decir, la semántica del mensaje. Como ejemplo, la especificación HTTP deja en claro que cuando un usuario envía una solicitud GET, no debe suponerse que el servidor desea hacer otra cosa que enviar una respuesta. – bdsl

3

(tanto la llamada al sistema como la utilidad` puede enviar casi cualquier señal a cualquier proceso, dado que tiene el permiso. Un proceso no puede distinguir cómo una señal cobró vida y quién lo envió.

Dicho esto, SIGINT realmente significa cantar la interrupción Ctrl-C, mientras que SIGTERM es la señal de terminal general. No hay concepto de que una señal sea "más enérgica", con la única excepción de que hay señales que no pueden ser bloqueado o manejado (SIGKILL y SIGSTOP, de acuerdo con la página de manual).

Una señal solo puede ser "más enérgica" que otra señal con respecto a cómo maneja un proceso de recepción 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, entonces no terminará su proceso, mientras que SIGINT todavía lo hace.

8

Como DarkDust observó que muchas señales tienen los mismos resultados, pero los procesos pueden asociarles diferentes acciones al distinguir cómo se genera cada señal. Al observar 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 entregan a cualquier hilo.

SA_KILL|SA_PROC,    /* SIGINT */ 
SA_KILL|SA_PROC,    /* SIGTERM */ 
+1

+1 gracias por "usar el código fuente!" Luke! –

7

Después de una rápida búsqueda en Google de sigint vs sigterm, parece que la única diferencia entre los dos es si se inició con un atajo de teclado o con una llamada explícita al kill.

Como resultado, podría, por ejemplo, interceptar sigint y hacer algo especial con él, sabiendo que probablemente se envió por un atajo de teclado. Quizás actualice la pantalla o algo así, en lugar de morir (no recomendado, ya que las personas esperan que ^C mate el programa, solo un ejemplo).

También me enteré de que ^\ debería enviar sigquit, que puedo comenzar a usar yo mismo. Parece muy útil.

4

Algunos son ANSI C y otros no

Una diferencia considerable es que:

  • SIGINT y SIGTERM son ANSI C, por lo tanto más fáciles de transportar
  • SIGQUIT y SIGKILL no son

Se describen en la sección "7.14 Gestión de señales" del C99 draft N1256:

  • SIGINT recepción de una señal de atención interactiva
  • SIGTERM una petición de terminación enviado al programa

que hace SIGINT un buen candidato para un sistema interactivo de Ctrl + C

Cuestiones relacionadas