Per rispondere a questa domanda, devi capire come i segnali vengono inviati a un processo e come esiste un processo nel kernel.
Ogni processo è rappresentato come task_struct
all'interno del kernel (la definizione è nel sched.h
file di intestazione e inizia qui ). Quella struttura contiene informazioni sul processo; per esempio il pid. Le informazioni importanti sono nella riga 1566 in cui è memorizzato il segnale associato. Questo è impostato solo se un segnale viene inviato al processo.
Un processo morto o un processo zombi ha ancora un task_struct
. La struttura rimane, fino a quando il processo genitore (naturale o per adozione) ha chiamato wait()
dopo aver ricevuto SIGCHLD
per raccogliere il suo processo figlio. Quando viene inviato un segnale, signal_struct
viene impostato. Non importa se il segnale è catchable o no, in questo caso.
I segnali vengono valutati ogni volta che viene eseguito il processo. O per essere precisi, prima che il processo si eseguisse. Il processo è quindi nello TASK_RUNNING
stato. Il kernel esegue la schedule()
routine che determina il prossimo processo in esecuzione secondo il suo algoritmo di pianificazione. Supponendo che questo processo sia il prossimo processo in esecuzione, signal_struct
viene valutato il valore di , indipendentemente dal fatto che vi sia un segnale di attesa da gestire o meno. Se un gestore di segnale viene definito manualmente (tramite signal()
o sigaction()
), viene eseguita la funzione registrata, in caso contrario viene eseguita l' azione predefinita del segnale . L'azione predefinita dipende dal segnale inviato.
Ad esempio, il SIGSTOP
gestore predefinito del segnale cambierà lo stato del processo corrente in TASK_STOPPED
e quindi eseguirà schedule()
per selezionare un nuovo processo da eseguire. Si noti che SIGSTOP
non è possibile accedere (come SIGKILL
), quindi non è possibile registrare un gestore di segnali manuale. In caso di segnale inattaccabile, verrà sempre eseguita l'azione predefinita.
Alla tua domanda:
Un pianificatore defunto o morto non sarà mai determinato dallo scheduler di essere TASK_RUNNING
nuovamente nello stato. Pertanto il kernel non eseguirà mai il gestore del segnale (predefinito o definito) per il segnale corrispondente, qualunque sia il segnale. Pertanto exit_signal
non verrà mai più impostato. Il segnale viene "consegnata" al processo impostando il signal_struct
in task_struct
del processo, ma niente altro accadrà, perché il processo non potrà mai funzionare ancora. Non c'è codice da eseguire, tutto ciò che rimane del processo è quella struttura del processo.
Tuttavia, se il processo genitore raccoglie i suoi figli da wait()
, il codice di uscita che riceve è quello quando il processo "inizialmente" è morto. Non importa se c'è un segnale in attesa di essere gestito.
kill
stesso restituisce 0 o 1?