- Un processo zombie è un processo figlio terminato che rimane nella tabella dei processi perché il suo padre non ha chiamato wait().
- Vengono rilevati con comandi come ps e top, dove appaiono con uno stato Z o etichettati come .
- Non consumano CPU, ma molti zombie possono riempire la tabella dei processi e causare seri problemi.
- Una pulizia corretta prevede di forzare il processo padre a raccogliere lo stato del figlio, utilizzando segnali come SIGHUP o SIGCHLD.
Nel mondo di GNU/Linux e degli altri sistemi UNIX, parlare di processi zombie non ha nulla a che vedere con serie TV o film horror, anche se il nome è piuttosto azzeccato. Si tratta di quei processi a metà tra vivi e morti che persistono nella tabella dei processi e, se si accumulano, possono causare non pochi grattacapi all'amministratore di sistema.
È importante capire cosa siano i processi zombie, come vengano creati, come rilevarli in Linux (e macOS ) e, soprattutto, come eliminarli senza danneggiare nulla di importante. Di seguito troverete una spiegazione dettagliata, che combina la teoria dei sistemi, esempi pratici con comandi come `ps` e ` top` , diversi metodi per terminare questi processi inattivi e persino un piccolo programma in C per generare un processo zombie di prova.
Cos'è esattamente un processo zombie in Linux?
Un processo zombie (o defunto) è un processo figlio che ha terminato l'esecuzione ma conserva ancora una voce nella tabella dei processi del sistema. Questa voce rimane affinché il processo padre possa interrogare il codice di uscita del figlio utilizzando chiamate come `wait()` o `waitpid()` . Finché il padre non esegue questa interrogazione, il figlio non scompare completamente.
In senso metaforico, il bambino è morto, ma la sua "anima" rimane registrata nel sistema. Per questo vengono chiamati zombie o processi morti: non eseguono più codice, non consumano CPU o memoria utente, ma occupano comunque un piccolo spazio nella tabella dei processi. Uno o due non sono un problema, ma se un'applicazione mal programmata ne genera molti, possono sorgere dei problemi.
Nei sistemi Unix e Linux, quando un processo termina, il kernel rilascia le sue risorse (memoria, descrittori di file, ecc.) ma conserva una traccia minima del suo stato di uscita. Se il processo padre non chiama mai `wait()` , questa traccia non viene cancellata e il processo rimane contrassegnato come zombie. Questo è quasi sempre un problema di programmazione o di progettazione nel software che funge da processo padre.
Questi processi sono facilmente riconoscibili perché in strumenti come ps appaiono con lo stato Z (per zombie) o con l'etichetta <defunct> , e in monitor come top ci sono contatori specifici che mostrano quanti zombie sono attivi nel sistema in un dato momento.

Stati del processo in Linux
Per comprendere il ruolo dei processi zombie, è utile esaminare gli stati di processo più comuni in Linux. Quando elenchiamo i processi con `ps` o `top` , una lettera indica lo stato:
- Dormire (S): processi inattivi, in attesa del loro turno per l'esecuzione o che si verifichi un evento.
- In esecuzione (R): processi in esecuzione sulla CPU o pronti per essere eseguiti.
- In attesa (D): processi bloccati in attesa del completamento di un'operazione di input/output (attesa ininterrotta).
- Fermato (T): processi interrotti, ad esempio, da segnali come SIGSTOP o perché sono in modalità debug.
- Zombi (Z): processi che sono terminati, ma continuano ad apparire nella tabella dei processi in attesa che il loro padre legga il loro stato di uscita.
Ogni riga in `ps` mostra un processo con il suo PID, PPID (PID padre), utente, stato e altri dati. Il campo stato può essere denominato S , STAT o qualcosa di simile, a seconda dei parametri di `ps`. Un processo con stato Z è, ufficialmente, uno zombie. In molti casi, il nome del processo o il comando verrà visualizzato come <defunct> , rendendo chiaro che è morto.
Come rilevare i processi zombie in Linux dal terminale
Il modo più diretto per individuare i processi zombie è utilizzare i classici comandi di monitoraggio: ps e top . Combinandoli con strumenti come grep , awk o xargs è possibile filtrare e preparare elenchi di PID con notevole precisione.
Uno dei comandi più utilizzati per vedere gli zombie è:
ps -el | grep 'Z'
Il parametro `-el` fa sì che `ps` visualizzi un output esteso, in cui la seconda colonna indica in genere lo stato del processo. In quella colonna possiamo trovare, tra le altre cose:
- S: dormire.
- R: corsa.
- D: attesa (attesa ininterrotta).
- T: fermato o gestopt (sospeso).
- Z: zombi (defunto).
Per fare un esempio più dettagliato, su una macchina con processi problematici potremmo ottenere qualcosa del tipo:
ps -el | grep 'Z'
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
1 Z 0 1213 589 0 75 0 – 0 funct> ? 00:00:00 dovecot-auth
Qui vediamo che il processo dovecot-auth è contrassegnato con lo stato Z, quindi è un processo zombie. Inoltre, osservate la colonna PPID , perché rappresenta il PID del processo padre, di cui parleremo più avanti per eliminare correttamente il processo zombie.
Un altro modo molto comune per elencare gli zombi è usare la combinazione:
ps -A -ostat,ppid,pid,cmd | grep -e '^'
In questo caso, l' opzione -A elenca tutti i processi, mentre l' opzione -o ci permette di definire esattamente quali colonne vogliamo: stato (stat), PPID, PID e comando. Il filtro grep -e '^' include solo le righe il cui stato inizia con Z oz, ovvero i processi zombie.
Un'altra opzione, un po' più minimalista, sarebbe:
ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'
In questa versione, richiediamo solo il PID e lo stato, senza intestazioni (utilizzando `pid=,stat=` ), e poi con `awk` filtriamo le righe il cui campo stato inizia con Z, stampando solo il PID del processo zombie. È un modo elegante per generare un elenco di PID di processi zombie da utilizzare in seguito con `kill` o altre pipeline.

Utilizzo di top per individuare i processi zombie
Il comando `top` è uno strumento interattivo molto pratico per visualizzare in tempo reale cosa sta succedendo sul sistema. L'intestazione di ` top` mostra un riepilogo che indica il numero totale di attività e quante se ne trovano in ciascuno stato, incluso il numero di processi zombie attivi .
Per utilizzarlo, basta eseguire:
top
Nella prima o nella seconda riga, vedrai qualcosa del tipo: Attività: 150 totali, 1 in esecuzione, 149 inattivi, 0 arrestati, 1 zombie . Questo contatore di zombie indica se ci sono processi terminati ancora attivi nel sistema. Inoltre, scorrendo l'elenco dei processi, nella colonna S (stato) , puoi individuare facilmente quelli contrassegnati da una Z.
Uno dei limiti di `top` è che, pur indicando il numero di processi zombie, non è sempre comodo come `ps` per estrarre solo quelli. Pertanto, è molto comune combinarli: prima `top` controlla la presenza di processi zombie, e poi si usa `ps` con i filtri che abbiamo visto per identificarli in dettaglio e preparare i comandi per eliminarli.
Alcuni articoli suggeriscono anche un altro comando specifico per visualizzare i processi inattivi con maggiori informazioni:
ps axo stat,ppid,pid,comm | grep -w defunct
Questo comando si concentra sui processi il cui comando è contrassegnato come non funzionante ; anche in questo caso verranno visualizzati lo stato, il PID del processo padre, il PID del processo figlio e il comando associato, il che semplifica notevolmente l'individuazione del problema e la sua derivazione dal processo padre.

Cosa succede nel kernel con un processo zombie
A livello interno del kernel Linux, ogni processo è rappresentato da una struttura dati chiamata `struct task_struct` . All'interno di questa struttura sono presenti campi che indicano lo stato del processo, tra cui `exit_state` , che è il campo in cui viene memorizzato lo stato di uscita quando il processo termina.
Quando un processo termina, il kernel lo contrassegna con un valore come EXIT_ZOMBIE (definito negli header del kernel) nel campo `exit_state` . Ciò significa che il processo è già terminato, ma è ancora in attesa che il processo padre recuperi le informazioni di uscita. Finché il processo padre non esegue `wait()` , il kernel non modifica questo stato né rimuove completamente la voce dalla tabella dei processi.
Il dettaglio interessante è che, sebbene un processo zombie non consumi una quantità significativa di CPU o memoria di lavoro, occupa comunque uno slot nella tabella dei processi . E questa tabella ha una dimensione finita. Se un'applicazione crea processi figli in un ciclo che non vengono mai terminati (perché il processo padre non chiama wait()), potremmo ritrovarci con centinaia o migliaia di processi zombie, esaurendo la capacità della tabella e causando errori durante la creazione di nuovi processi.
Come terminare i processi zombie in Linux
Una volta individuati i processi zombie, dobbiamo pensare a come "terminarli" efficacemente. Ecco un punto chiave: il processo zombie è già morto , nel senso che non è più in esecuzione. Pertanto, inviare segnali come SIGKILL (kill -9) direttamente allo zombie è inutile; non c'è codice che risponda a quel segnale.
Ciò che è realmente necessario fare è indurre il processo padre a leggere lo stato di uscita del processo figlio . Questo può essere ottenuto in diversi modi: inviando segnali appropriati al padre, forzando la terminazione del padre (in modo che init o systemd possano rilevare il processo zombie e ripulirlo), oppure utilizzando combinazioni di comandi che automatizzano questa operazione.
Prima opzione: inviare SIGHUP al genitore
Una soluzione ampiamente utilizzata prevede di trovare il PPID dei processi zombie e di inviare un segnale al processo padre per eseguire `wait()` e raccogliere lo stato dei suoi processi figli. Un comando tipico è:
kill -HUP `ps -A -ostat,ppid,pid,cmd | grep -e '^' | awk '{print $2}'`
Ecco cosa succede: innanzitutto, tutti i processi vengono elencati con il loro stato, PPID, PID e comando; poi, vengono filtrati quelli il cui stato inizia con Z; infine, la seconda colonna, che è il PPID (l'identificativo del processo padre), viene estratta usando `awk '{print $2}'` . Questo elenco di PID padre viene quindi passato a `kill -HUP` , che invia il segnale SIGHUP a ciascuno di essi.
In molte applicazioni, questo segnale induce il processo padre a ricaricare la propria configurazione o a eseguire alcune operazioni di pulizia. In questo contesto, l'idea è che il processo padre esegua un'apposita funzione wait() e si sbarazzi dei processi zombie . Si tratta di un metodo piuttosto aggressivo ma pratico, soprattutto quando sono presenti molti processi zombie accumulati che condividono lo stesso processo padre.
Seconda opzione: utilizzare SIGCHLD
Un altro approccio consiste nell'inviare il segnale SIGCHLD al processo padre problematico. Questo segnale comunica a un processo che uno dei suoi figli ha cambiato stato (ad esempio, è terminato). In genere, quando un processo figlio termina, il kernel invia SIGCHLD al padre; se il padre ha un gestore di segnali configurato, di solito chiama wait() all'interno di tale gestore.
Se rilevi che più zombie hanno lo stesso PPID, puoi provare:
kill -s SIGCHLD
Ad esempio:
kill -s SIGCHLD 2201
Questo ricorda al processo padre che ha processi figli non terminati. Se il processo padre è programmato correttamente per reagire al segnale SIGCHLD, eliminerà i suoi processi zombie utilizzando wait(). Questo metodo è meno brusco rispetto alla terminazione del processo padre e, se il programma è ben scritto, è il modo più naturale per risolvere il problema.
Terza opzione: uccidere il processo padre
Se il processo padre è bloccato, non risponde a segnali come SIGHUP o SIGCHLD, o è chiaramente bloccato, un'altra opzione è quella di terminarlo forzatamente. In questo caso, si utilizza il metodo classico:
uccidi -9
Ad esempio:
kill -9 2201
In questo modo, il kernel termina il processo padre. Nella maggior parte dei sistemi moderni, systemd o il processo init si occupano dei processi orfani (inclusi gli zombie) e chiamano la funzione wait() su di essi, eliminando così la loro voce dalla tabella dei processi. Non è l'approccio più elegante, ma a volte è l'unico modo per sbarazzarsi di un gruppo di processi zombie originati da un programma difettoso.
Altre combinazioni avanzate con ps, awk e kill
Oltre agli esempi sopra riportati, esistono molti one-liner che automatizzano la ricerca di zombie e l'invio di segnali ai processi padre. Alcuni esempi rappresentativi sono:
ps axo stato,pid | awk '$1==»2″ {stampa $2}' | xargs kill -s SIGKILL
Questo comando seleziona i processi in base al valore numerico del loro stato; tuttavia, viene utilizzato meno frequentemente perché è meno leggibile rispetto al lavoro con la lettera Z. Altri comandi comuni per gestire gli zombie sono:
ps -xaw -o stato,ppid | grep Z | grep -v PID | awk '{ print $2 }' | xargs kill -9
Oh bene:
kill -9 `ps xawo state=,pid= | sed -n 's/Z //p'`
o anche:
kill -9 `ps -xaw -o state -o ppid | grep Z | grep -v PID | awk '{print $2}'`
In tutti i casi, l'idea è simile: individuare i processi nello stato Z, estrarre i loro PID o i corrispondenti PPID e applicare il comando di terminazione con il segnale appropriato (SIGHUP, SIGCHLD, SIGKILL, ecc.). Tuttavia, questi metodi devono essere utilizzati con cautela, perché terminare processi padre importanti senza considerarne le conseguenze può causare il blocco dei servizi o l'instabilità del sistema.
Esempio pratico: creazione di un processo zombie con C
Per eseguire i test senza causare danni, una tecnica classica consiste nel creare un processo zombie in modo controllato utilizzando un piccolo programma in C. In questo modo, possiamo vedere esattamente come appare in ps, come viene contrassegnato come <defunct> e fare pratica con i comandi per rimuoverlo.
Un programma molto semplice che genera uno zombie potrebbe essere questo:
#includere
#include
#includere
intero principale ()
{
pid_t child_pid;
child_pid = fork();
se (child_pid > 0) {
dormire (60);
}
else {
uscita (0);
}
0 ritorno;
}
In questo codice, il processo padre esegue una fork() . Il processo figlio termina immediatamente con exit(0) , mentre il padre rimane inattivo per 60 secondi . Durante questo periodo, il processo figlio è inattivo, ma il padre non ha ancora chiamato wait() , quindi il figlio rimane in uno stato zombie nella tabella dei processi.
Per compilare questo programma puoi usare gcc nel modo seguente:
gcc -o zombie1 zombie.c
Per eseguirlo in background, basta semplicemente:
./zombie1 &
Mentre il processo padre è ancora inattivo, puoi eseguire `ps -el | grep 'Z'` o uno qualsiasi dei comandi sopra menzionati e vedrai il processo zombie in azione. Dopo alcuni secondi, quando il processo padre termina e il sistema esegue la pulizia, il processo zombie scomparirà.
Impatto dei processi zombie e cause comuni
Un singolo processo zombie isolato di solito non è motivo di preoccupazione . Non consuma CPU, la memoria associata al processo è già stata liberata e l'impatto diretto sulle prestazioni è minimo. Il problema sorge quando si accumulano molti processi zombie, in genere a causa di una progettazione inadeguata del software o di bug nella gestione dei processi figli.
Le cause più frequenti degli zombi sono:
- Programmazione scadenteIl processo padre crea processi figlio ma non implementa correttamente la gestione SIGCHLD né chiama wait() o waitpid() per raccogliere lo stato dei figli.
- errori di configurazioneAlcuni servizi potrebbero creare processi figlio in un ciclo in determinate configurazioni non previste dallo sviluppatore, generando una cascata di zombie.
- Il processo padre si blocca o si arresta in modo anomaloSe il genitore rimane bloccato in un'operazione di I/O o in un ciclo infinito, può lasciare i figli morti non ripuliti.
Quando sono presenti molti processi zombie, la tabella dei processi può riempirsi di voci inattive , rendendo difficile la creazione di nuovi processi e generando sintomi come rallentamenti, errori all'avvio delle applicazioni o comportamenti anomali nei servizi critici (ad esempio, server web come Apache che generano centinaia di processi inattivi).
Pertanto, è importante controllare periodicamente con `top` o `ps` la presenza di processi zombie, soprattutto sui server di produzione, e soprattutto correggere la causa principale: aggiornare il software problematico, correggere il codice che gestisce i processi figli o modificare le configurazioni che causano la creazione incontrollata di processi figli.
Alternative grafiche per gli utenti desktop
Se non ti trovi a tuo agio con il terminale o preferisci semplicemente una soluzione visiva, in molti ambienti grafici Linux puoi utilizzare Monitor di sistema o strumenti equivalenti che offrono una visualizzazione grafica dei processi.
La procedura generale sarebbe più o meno questa:
- Apri l'app Monitor di sistema dal menu del desktop.
- Vai alla scheda processi, dove sono elencati tutti i processi attivi.
- Utilizzare lo strumento di ricerca (solitamente un'icona a forma di lente di ingrandimento) per cercare termini come zombie oppure guarda la colonna di stato per individuare i processi contrassegnati come o Z.
- Selezionare il processo problematico, fare clic con il pulsante destro del mouse e scegliere l'opzione per "Uccisione" o "Termina processo".
Affinché funzioni correttamente, è fondamentale assicurarsi che il monitor visualizzi tutti i processi di sistema , non solo quelli dell'utente corrente. Solitamente, nelle impostazioni è presente una casella di controllo o un'opzione che consente di "Mostrare i processi di tutti gli utenti" o qualcosa di simile.
Buone pratiche per prevenire la proliferazione degli zombie
Oltre ai trucchi per eliminare gli zombie una volta che si sono manifestati, è opportuno applicare alcune buone pratiche per ridurre al minimo il verificarsi di questi processi nei sistemi di produzione.
Tra le raccomandazioni più importanti ci sono:
- Mantenere il sistema e il software aggiornatiSpesso i processi zombie derivano da bug che sono già stati risolti nelle versioni successive di un server o di un'applicazione.
- Rivedere la pianificazione dei processi figlioSe sviluppi software che utilizza fork(), assicurati di gestire correttamente SIGCHLD e di chiamare wait() o waitpid() per ogni figlio che termina.
- Monitorare periodicamenteL'inserimento di comandi come ps -el, ps axo stat,ppid,pid,comm o top negli script di monitoraggio o negli strumenti di osservabilità aiuta a rilevare immediatamente i picchi di zombie.
- Indagare sull'origine quando compaiono gli zombi ricorrentiSe sono sempre figli di un servizio specifico (ad esempio, un server di posta o un demone specifico), potrebbe essere necessario rivederne la configurazione o la versione.
In alcuni casi, sono stati persino pubblicati script specifici (ad esempio, chiamati zombi.sh ) che automatizzano tutta questa logica: individuano i processi zombie, identificano i loro processi padre, inviano i segnali appropriati e tentano di svuotare la tabella dei processi. Sono utili come ultima risorsa quando i metodi manuali falliscono, ma è sempre importante sapere cosa fanno dietro le quinte per evitare sorprese.
In breve, capire cos'è un processo zombie, come visualizzarlo con `ps` e `top` , come i segnali `SIGHUP` , `SIGCHLD` e `SIGKILL` influenzano i processi padre e quali modelli di programmazione portano a questo stato consente di diagnosticare e risolvere facilmente praticamente qualsiasi problema relativo ai processi terminati in Linux, mantenendo i sistemi più puliti, più stabili e con la tabella dei processi sotto controllo.
Scrittore appassionato del mondo dei byte e della tecnologia in generale. Adoro condividere le mie conoscenze attraverso la scrittura, ed è quello che farò in questo blog, mostrarti tutte le cose più interessanti su gadget, software, hardware, tendenze tecnologiche e altro ancora. Il mio obiettivo è aiutarti a navigare nel mondo digitale in modo semplice e divertente.
Contenuti
- 1 Cos'è esattamente un processo zombie in Linux?
- 2 Stati del processo in Linux
- 3 Come rilevare i processi zombie in Linux dal terminale
- 4 Utilizzo di top per individuare i processi zombie
- 5 Cosa succede nel kernel con un processo zombie
- 6 Come terminare i processi zombie in Linux
- 7 Esempio pratico: creazione di un processo zombie con C
- 8 Impatto dei processi zombie e cause comuni
- 9 Alternative grafiche per gli utenti desktop
- 10 Buone pratiche per prevenire la proliferazione degli zombie