I segnali sono uno dei meccanismi più importanti e interessanti per interagire col vostro sistema *nix. Il programma kill, a discapito del nome, può essere utilizzato per l’invio di un segnale ed uno specifico processo. Mentre il pid del processo da segnalare è obbligatorio, se non specificato, il segnale di default che viene inviato è un SIGTERM.

Oltre ad uccidere un processo, kill può essere utilizzato per interagire con un programma, ad esempio esiste una convenzione per cui inviando un SIGHUP ad un daemon questo ricaricherà la sua configurazione.

Il runtime di C definisce 6 segnali standard, mentre su Linux ne abbiamo 21 in totale. Il comportamento di default è stabilito dal file signal.h. In generale, i default sono:

  • Termina il programma
  • Ignora il segnale

kill -SIGTERM <pid>

Come detto poco fa, il segnale di default che viene inviato ad un processo da parte di kill, è SIGTERM.

Non appena il segnale viene recapitato al destinatario può accedere una delle seguenti cose:

  • Il processo potrebbe uscire immediatamente.
  • Il processo potrebbe liberare delle risorse allocate (chiudere connessioni aperte, rimuovere file temporanei etc.) e quindi uscire dopo un piccolo intervallo di tempo.
  • Il processo potrebbe continuare a girare per tempo indefinito.

Come per la maggior parte dei segnali, un processo può installare un singal handler per modificare le azioni da eseguire alla ricezione di un SIGTERM (che, ripetiamolo, di default porterebbe alla terminazione del programma).

Inoltre, se il processo si trova in uno stato bloccante (ad esempio aspettando la risposta ad una richiesta I/O), non potrà gestire il segnale appena recapitatogli.

A questo punto quindi, la maggior parte degli amministratori di sistema passerà alle maniere forti

kill -9 <pid>

Kill prevede la possibilità di specificare il segnale da inviare in 3 modi differenti:

  • Usando il numero: -9
  • Usando il nome usando il prefisso SIG: -SIGKILL
  • Usando il nome del segnale: -KILL

In generale -9 è più corto di SIGKIL da digitare, ed è quindi comune usare la versione a numero. Per gli altri segnali invece è più conveniente usare il loro nome.

Per avere la lista completa dei segnali ed altre informazioni, si rimanda al manuale: man 7 signal.

man 7 signal

Tornando al fulcro della sezione, SIGKILL è un segnale molto speciale: questo infatti non viene recapitato al processo destinatario, bensì al kernel sottostante che prenderà in carico la richiesta e forzerà la terminazione del processo.

Non essendo recapitato al processo destinatario, SIGKILL di fatto non può essere gestito.

Esistono alcune eccezioni però in cui neanche SIGKILL può fare nulla:

  1. Non è possibile inviare un SIGKILL al processo di init (il kernel ci proteggerà evitando di terminarlo).
  2. Non è possibile inviare un SIGKILL ad un processo in stato zombie
  3. Infine, non è possibile inviare un segnale ad un processo instato Uninterruptible sleep o Blocked(come già detto in precedenza può succedere durante le richieste I/O).

Conclusione

In generale è sempre preferibile dare la possibilità ad un processo di liberare le proprie risorse in maniera corretta, inviando un SIGTERM. Se è stato installato un signal handler, il processo sà che deve liberare le risorse e terminare il prima possibile.

Se dopo qualche secondo il processo risulti ancora in esecuzione, potrebbe essere il caso di inviare un SIGKILL.

Nel caso in cui neanche la SIGKILL riesca ad essere efficace, potrebbe essere richiesto un riavvio di sistema.