2013-12-15 7 views
5

Mi chiedo se il seguente codice può creare zombie:Questo codice C può creare processi di zombi?

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

int main(){ 
    int i=1; 
    pid_t p; 
    p = fork(); 
    i++; 
    if(p!=0){ 
     waitpid(p, NULL, 0); 
    } 
    printf("%d\n",i); 
    return 0; 
} 

Quindi, il processo padre chiama la waitpid per il processo figlio, che restituisce immediatamente se il bambino non sia già uscito. Quindi, nessun zombi può sorgere finora. Ma se il bambino esce prima del comando

return 0;
, allora sarebbe uno zombi? Sono davvero confuso a riguardo. L'waitpid dovrebbe essere l'ultima riga di codice prima che il programma termini? Qualsiasi aiuto sarebbe apprezzato. Grazie!

+1

Sembra ok ma potresti avere un malinteso. L''waitpid' ritornerà immediatamente se il bambino è già morto; altrimenti bloccherà fino a quando il bambino non muore. A meno che non usi WNOHANG con waitpid, nel qual caso non bloccherà ma non è in discussione qui. – Duck

+0

Correggimi se sbaglio, ma penso che il terzo parametro (zero) sia equivalente a WHOHANG. Ad ogni modo, supponiamo che fosse WHOHANG. Verrà creato uno zombie e come? E infine, l'waitpid dovrebbe essere l'ultimo comando prima di restituire 0; per garantire che nessuno zombi sarà creato ?. Grazie ancora! – mgus

+1

No WNOHANG non è sicuramente equivalente a 0. Zero è il valore predefinito e non avrebbe senso bitwise o WNOHANG se fosse uguale a 0. Se il bambino è morto dopo un 'waitpid non bloccante' e il genitore è uscito prima, allora avrebbe uno zombi. Ma normalmente si usa un 'waitpid' non bloccante in un ciclo e possibilmente in combinazione con la ricezione di SIGCHLD. Waitpid stesso può trovarsi ovunque nel codice fintanto che gestisce i tuoi figli quando viene chiamato a farlo. – Duck

risposta

6

Il bambino diventa solo uno zombie se finisce e il genitore non chiama wait*()finché stesso a vivere.

Nel momento in cui il genitore finisce anche il bambino è raccolto dal processo init che si occuperà di chiamare wait*() sul bambino, in modo che finalmente fine e con questo lasciare lo stato di zombie e scompare dalla lista dei processi.

a provocare il figlio creato nel codice di esempio per diventare uno zombie modificare il codice, ad esempio come segue:

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

int main(void) 
{ 
    pid_t p = fork(); 

    if (p != 0) 
    { 
     waitpid(p, NULL, 0); /* See if the child already had ended. */ 
     sleep(1); /* Wait 1 seconds for the child to end. And eat away the SIGCHLD in case if arrived. */ 
     pause(); /* Suspend main task. */ 
    } 
    else 
    { 
     sleep(3); /* Just let the child live for some tme before becoming a zombie. */ 
    } 

    return 0; 
} 

A causa delle due seguenti fatti:

  • il bambino dorme per 3s quindi la chiamata del genitore a waitpid() probabilmente fallirà sempre
  • la gestione di default di SIGCHLD è di ignorarlo.

il codice precedente infatti è uguale a:

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

int main(void) 
{ 
    pid_t p = fork(); 

    if (p != 0) 
    { 
     pause(); /* Suspend main task. */ 
    } 
    else 
    { 
     sleep(3); /* Just let the child live for some tme before becoming a zombie. */ 
    } 

    return 0; 
} 
+0

Cosa c'è in questo codice che impedisce al bambino di diventare uno zombi? Puoi spiegare più in dettaglio perché hai usato i comandi sleep e pause? Ci scusiamo per così tante domande ma non ho familiarità con queste nozioni. – mgus

+0

@ Konstantinidis Konstantinidis: "* Cosa c'è in questo codice che impedisce al bambino di diventare uno zombi? *" Niente. Come affermato nella mia risposta, questo codice ** fa ** creare uno zombie. – alk

0

Ho trovato un modo semplice per creare un processo zombie e testare utilizzando ps -e

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 

void main() 
{ 
    pid_t pid; 
    pid = fork(); 
    //parent sleeps while the child has exited 
    //not an orphan since parent still alive 
    //child will be still present in process table 
    if(pid==0) 
    {//child 
     exit(0); 
    } 
    else 
    {//parent 
     sleep(15); 
    } 
} 

run ps - e mentre entro i 15 secondi ... vedrai

6454 pts/2 00:00:00 a.out < defunto>

Problemi correlati