Enviar kill -9 a un proceso no requiere la cooperación del proceso (como manejar una señal), solo lo elimina.
Supone que, debido a que algunas señales pueden captarse e ignorarse, todas implican cooperación. Pero según man 2 signal
"las señales SIGKILL y SIGSTOP no pueden ser captadas o ignoradas". SIGTERM puede ser atrapado, por lo que el simple kill
no siempre es efectivo, generalmente esto significa que algo en el controlador del proceso ha salido mal. 1
Si un proceso no (o no puede) definir un controlador para una señal dada, el kernel realiza una acción predeterminada. En el caso de SIGTERM y SIGKILL, esto es para terminar el proceso (a menos que su PID sea 1; el núcleo no terminará init
) 2, lo que significa que sus identificadores de archivo están cerrados, su memoria regresó al grupo de sistemas, su padre recibe SIGCHILD, su huérfano los hijos son heredados por init, etc., como si hubiera llamado exit
(ver man 2 exit
). El proceso ya no existe, a menos que termine como un zombi, en cuyo caso todavía aparece en la tabla de proceso del núcleo con alguna información; eso sucede cuando su padre nowait
y lidiar con esta información correctamente. Sin embargo, los procesos zombie ya no tienen memoria asignada y, por lo tanto, no pueden continuar ejecutándose.
¿Hay algo así como una tabla global en la memoria en la que Linux mantiene referencias a todos los recursos ocupados por un proceso y cuando "mato" un proceso, Linux simplemente pasa por esa tabla y libera los recursos uno por uno?
Creo que eso es lo suficientemente preciso. Se realiza un seguimiento de la memoria física por página (una página generalmente equivale a un fragmento de 4 KB) y esas páginas se toman y se devuelven a un grupo global. Es un poco más complicado porque algunas páginas liberadas se almacenan en caché en caso de que los datos que contienen se vuelvan a requerir (es decir, datos que se leyeron de un archivo aún existente).
Las páginas de manual hablan de "señales", pero seguramente eso es solo una abstracción.
Claro, todas las señales son una abstracción. Son conceptuales, al igual que los "procesos". Estoy jugando semántica un poco, pero si te refieres a SIGKILL es cualitativamente diferente de SIGTERM, entonces sí y no. Sí en el sentido de que no se puede atrapar, pero no en el sentido de que ambas son señales. Por analogía, una manzana no es una naranja, pero las manzanas y las naranjas son, según una definición preconcebida, ambas frutas. SIGKILL parece más abstracto ya que no puedes atraparlo, pero sigue siendo una señal. Aquí hay un ejemplo de manejo de SIGTERM, estoy seguro de que has visto esto antes:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
void sighandler (int signum, siginfo_t *info, void *context) {
fprintf (
stderr,
"Received %d from pid %u, uid %u.\n",
info->si_signo,
info->si_pid,
info->si_uid
);
}
int main (void) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &sa, NULL);
while (1) sleep(10);
return 0;
}
Este proceso dormirá para siempre. Puede ejecutarlo en una terminal y enviarlo con SIGTERM kill
. Escupe cosas como:
Received 15 from pid 25331, uid 1066.
1066 es mi UID. El PID será el del shell desde el cual kill
se ejecuta, o el PID de kill si lo bifurcas ( kill 25309 & echo $?
).
Nuevamente, no tiene sentido establecer un controlador para SIGKILL porque no funcionará. 3 Si yo kill -9 25309
el proceso terminará. Pero eso sigue siendo una señal; el kernel tiene la información sobre quién envió la señal , qué tipo de señal es, etc.
1. Si no ha mirado la lista de posibles señales , vea kill -l
.
2. Otra excepción, como menciona Tim Post a continuación, se aplica a procesos en suspensión ininterrumpida . No se pueden despertar hasta que se resuelva el problema subyacente, por lo que TODAS las señales (incluida SIGKILL) se difieren por la duración. Sin embargo, un proceso no puede crear esa situación a propósito.
3. Esto no significa que usar kill -9
es algo mejor que hacer en la práctica. Mi controlador de ejemplo es malo en el sentido de que no conduce a exit()
. El verdadero propósito de un controlador SIGTERM es darle al proceso la oportunidad de hacer cosas como limpiar archivos temporales y luego salir voluntariamente. Si lo usa kill -9
, no tiene esta oportunidad, así que solo haga eso si la parte de "salir voluntariamente" parece haber fallado.
kill -9
referencia .