Proces zombie

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 8 iunie 2019; verificările necesită 5 modificări .

Zombie process , zombie ( eng.  zombie process , eng.  defunct process ) - un proces copil într-un sistem Unix care și-a încheiat execuția, dar este încă prezent în lista de procese ale sistemului de operare pentru a permite procesului părinte să citească codul de ieșire .

Etimologie

Derivat din cuvântul „ zombie ”, care înseamnă „mort vii” ( oximoron , engleză  strigoi ). Termenul este o metaforă vie a faptului că procesul este „mort”, dar nu „îngropat”.

Ascensiunea zombie

Un proces, atunci când este terminat (fie în mod normal, fie ca urmare a unui semnal necontrolat), eliberează toate resursele sale și devine un „zombie” - o intrare goală în tabelul de proces care stochează starea de ieșire pentru a fi citită de procesul părinte.

Un proces zombi există până când procesul părinte își citește starea cu un apel de sistem wait() , ceea ce face ca intrarea în tabelul de procese să fie eliberată.

Când un proces se termină, sistemul notifică procesul părinte cu privire la terminarea copilului cu semnalul SIGCHLD , așa că poate fi convenabil (dar nu necesar) să apelați wait()un handler pentru acest semnal.

Zombie Trouble

Zombii nu ocupă memorie (cum ar fi procesele orfane ), ci blochează intrările în tabelul de procese, care este limitat în dimensiune pentru fiecare utilizator și pentru sistemul în ansamblu.

Când limita de scriere este atinsă, toate procesele utilizatorului care rulează procesul părinte care creează zombi nu vor putea crea noi procese copil. În plus, utilizatorul sub numele căruia rulează procesul părinte nu se va putea autentifica în consolă (locală sau la distanță) sau nu va putea executa comenzi pe o consolă deja deschisă (deoarece interpretul de comenzi sh trebuie să creeze un nou proces pentru aceasta) , iar pentru restabilirea sănătății (încheierea programului infracțional) va fi necesară intervenția administratorului de sistem.

Uneori, dacă procesul părinte rulează în numele superutilizatorului, poate fi necesară o repornire pentru a elibera înregistrările (repornirea procesului) (și adesea doar o repornire greută). Unele sisteme de operare (cum ar fi Sun Solaris ) vor bloca unele dintre procesele care rulează atunci când apare această situație, restabilind sistemul la starea de sănătate.

Fiecare proces este într-o stare zombie când se termină și până când starea de terminare este citită de un strămoș, acest lucru este perfect normal și procesele zombie de scurtă durată nu sunt o problemă în sistem. În același timp, o serie de erori de programare pot duce la apariția și acumularea de procese zombie neprocesate în sistem (adică procese care s-au încheiat deja, al căror părinte nu le citește starea).

Ignorarea proceselor de terminare a proceselor copil nu este corectă, dar de obicei nu duce la probleme pentru programele de scurtă durată, deoarece atunci când un proces se termină, toți copiii săi devin copii ai procesului init, care citește constant starea copiilor săi zombi, ștergând tabelul de proces. Pentru a activa acest mecanism este efectuată tehnica standard de pornire a demonului „double fork()”: părintele intermediar se termină, făcând procesul părinte al fiului său init.

Pentru programele de lungă durată și care creează frecvent copii, controlul de terminare a programului copil trebuie gestionat corect, deoarece acumularea de zombi netratați duce la o „scurgere de resurse” sub forma unei acumulări de intrări în tabelul de proces.

În Linux, pornind de la kernelul 3.4, un proces are capacitatea de a se declara adoptator orfan ("subreaper") în loc de un proces cu initcomanda prctl(PR_SET_CHILD_SUBREAPER).

Exemple de programe care creează zombi în diverse limbaje de programare

Xi

#include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main () { pid_t child_pid ; child_pid = furculiță (); if ( child_pid > 0 ) { somn ( 60 ); } else { ieșire ( 0 ); } returnează 0 ; }

Python

#!/usr/bin/env python2 # -*- codificare: utf8 -*- import subproces timp import import threading # Apariția procesului „ls” cu opțiunea „-l” proc = subproces . Popen ([ 'ls' , '-l' ]) # Opriți firul principal al programului timp de 5 secunde. În timpul acestui proces, # procesul va avea statutul de „zombi”, chiar dacă procesul a ieșit deja deoarece rezultatul procesului de # timp nu a fost procesat . somn ( 5 ) # În acest loc, zombiul va dispărea, pentru că. programul va șterge tampoanele I/O pentru procesul # și va citi codul de ieșire proc . comunica () timp . somn ( 5 )

Diverse

  • Zombii nu pot primi semnale și, prin urmare, nu pot fi uciși cu un utilitar sau un apel de ucidere . Fie procesul părinte, fie încetarea acestuia le poate elimina.
  • Toate procesele din Unix au proprii lor părinți - procesele care nu au sau și-au pierdut părinți ( procese „orfane” ; proces orfan în engleză  ) sunt copii ai init (un proces cu PID = 1), care, la rândul său, este un copil al lui. nucleul (proces cu PID = 0). init procesează întotdeauna SIGCHLD, astfel încât astfel de procese nu părăsesc niciodată zombi.
  • Zombii pot fi recunoscuți în lista de procese (afișată de utilitarul ps ) prin steagul „Z” din coloana STAT.
  • Se consideră un stil de programare bun să se ocupe întotdeauna de SIGCHLD.
  • Limbile de scripting Perl și Python se ocupă implicit de SIGCHLD dacă programul îl configurează pentru a fi ignorat.

Vezi și