Quando killall -9 name
uccidevo un programma, lo stato diventava zombi. Alcuni minuti dopo, si è fermato davvero. Quindi, cosa sta succedendo in quei minuti?
Quando killall -9 name
uccidevo un programma, lo stato diventava zombi. Alcuni minuti dopo, si è fermato davvero. Quindi, cosa sta succedendo in quei minuti?
Risposte:
Il programma in realtà non riceve mai il segnale SIGKILL, poiché SIGKILL è completamente gestito dal sistema operativo / kernel.
Quando viene inviato SIGKILL per un processo specifico, lo scheduler del kernel smette immediatamente di concedere a quel processo altro tempo CPU per l'esecuzione del codice spazio utente. Se il processo ha dei thread che eseguono il codice dello spazio utente su altre CPU / core nel momento in cui lo scheduler prende questa decisione, anche questi thread verranno arrestati. (Nei sistemi single-core questo era molto più semplice: se l'unico core della CPU nel sistema eseguiva lo scheduler, per definizione non eseguiva il processo allo stesso tempo!)
Se il processo / thread sta eseguendo il codice del kernel (ad esempio una chiamata di sistema o un'operazione I / O associata a un file mappato in memoria) al momento di SIGKILL, diventa un po 'più complicato: solo alcune chiamate di sistema sono interrompibili, quindi il il kernel contrassegna internamente il processo in uno stato speciale "morente" fino a quando il sistema chiama o le operazioni di I / O vengono risolte. Il tempo della CPU per risolverli verrà programmato come al solito. Le chiamate di sistema interrompibili o le operazioni di I / O verificheranno che il processo che le ha chiamate stia morendo in tutti i punti di arresto adeguati e in quel caso uscirà presto. Le operazioni ininterrotte verranno completate e verificheranno lo stato "morente" appena prima di ritornare al codice dello spazio utente.
Una volta risolte le routine del kernel in-process, lo stato del processo passa da "morendo" a "morto" e il kernel inizia a ripulirlo, come quando un programma esce normalmente. Una volta completata la pulizia, verrà assegnato un codice risultato superiore a 128 (per indicare che il processo è stato interrotto da un segnale; vedere questa risposta per i dettagli disordinati ) e il processo passerà allo stato "zombi" . Il genitore del processo ucciso verrà avvisato con un segnale SIGCHLD.
Di conseguenza, il processo stesso non avrà mai la possibilità di elaborare effettivamente le informazioni che ha ricevuto un SIGKILL.
Quando un processo è in uno stato "zombi" significa che il processo è già morto, ma il suo processo genitore non lo ha ancora riconosciuto leggendo il codice di uscita del processo morto usando la wait(2)
chiamata di sistema. Fondamentalmente l'unica risorsa che un processo zombi sta consumando di più è uno slot nella tabella dei processi che contiene il suo PID, il codice di uscita e alcune altre "statistiche vitali" del processo al momento della sua morte.
Se il processo genitore muore prima dei suoi figli, i processi figlio orfani vengono automaticamente adottati dal PID n. 1, che ha il dovere speciale di continuare a chiamare in wait(2)
modo che eventuali processi orfani non rimangano come zombi.
Se ci vogliono diversi minuti per completare un processo di zombi, ciò suggerisce che il processo genitore dello zombi sta lottando o non sta facendo il suo lavoro correttamente.
C'è una descrizione ironica su cosa fare in caso di problemi con gli zombi nei sistemi operativi simili a Unix: "Non puoi fare nulla per gli stessi zombi, poiché sono già morti. Invece, uccidi il malvagio maestro di zombi! " (cioè il processo genitore degli zombi fastidiosi)
ps
: 'S' sta per I / O in attesa che il kernel possa annullare per inviare un segnale, e 'D' per quelli che non può.