Para responder a esa pregunta, debe comprender cómo se envían las señales a un proceso y cómo existe un proceso en el núcleo.
Cada proceso se representa task_struct
dentro del núcleo (la definición está en el sched.h
archivo de encabezado y comienza aquí ). Esa estructura contiene información sobre el proceso; por ejemplo el pid. La información importante está en la línea 1566 donde se almacena la señal asociada. Esto se establece solo si se envía una señal al proceso.
Un proceso muerto o un proceso zombie todavía tiene un task_struct
. La estructura permanece, hasta que el proceso padre (natural o por adopción) ha llamado wait()
después de recibir SIGCHLD
para cosechar su proceso hijo. Cuando se envía una señal, signal_struct
se establece. No importa si la señal es atrapable o no, en este caso.
Las señales se evalúan cada vez que se ejecuta el proceso. O para ser exactos, antes de que el proceso se ejecute. El proceso está entonces en el TASK_RUNNING
estado. El núcleo ejecuta la schedule()
rutina que determina el siguiente proceso de ejecución de acuerdo con su algoritmo de programación. Suponiendo que este proceso es el siguiente proceso en ejecución, signal_struct
se evalúa el valor del mismo , ya sea que haya una señal de espera para ser manejada o no. Si un controlador de señal se define manualmente (a través de signal()
o sigaction()
), se ejecuta la función registrada, si no se ejecuta la acción predeterminada de la señal . La acción predeterminada depende de la señal que se envía.
Por ejemplo, el SIGSTOP
controlador predeterminado de la señal cambiará el estado del proceso actual a TASK_STOPPED
y luego se ejecutará schedule()
para seleccionar un nuevo proceso a ejecutar. Tenga en SIGSTOP
cuenta que no es capturable (como SIGKILL
), por lo tanto, no hay posibilidad de registrar un controlador de señal manual. En caso de una señal que no se puede capturar, la acción predeterminada siempre se ejecutará.
A su pregunta:
El planificador nunca determinará que un proceso inactivo o inactivo esté TASK_RUNNING
nuevamente en el estado. Por lo tanto, el núcleo nunca ejecutará el controlador de señal (predeterminado o definido) para la señal correspondiente, cualquiera que sea la señal. Por lo tanto exit_signal
, nunca se volverá a configurar. La señal se "entrega" al proceso mediante el establecimiento de la signal_struct
en task_struct
el proceso, pero nada más va a pasar, porque el proceso nunca se ejecutará de nuevo. No hay código para ejecutar, todo lo que queda del proceso es esa estructura del proceso.
Sin embargo, si el proceso padre cosecha a sus hijos wait()
, el código de salida que recibe es el que se produjo cuando el proceso "inicialmente" murió. No importa si hay una señal esperando a ser manejada.
kill
sí devuelve 0 o 1?