2013-12-15 9 views
5

Ich frage mich, ob der folgende Code Zombies erstellen:Kann dieser C-Code Zombie-Prozesse erzeugen?

#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; 
} 

So ruft der Eltern-Prozess den waitpid für das Kind Prozess, der sofort zurück, wenn das Kind nicht bereits verlassen hat. Also, bis jetzt können keine Zombies entstehen. Aber wenn das Kind vor

return 0;
das Kommando verlässt, wäre das dann ein Zombie? Ich bin wirklich verwirrt darüber. Sollte die waitpid die letzte Codezeile sein, bevor das Programm beendet wird? Jede Hilfe wäre willkommen. Vielen Dank!

+1

Das sieht gut aus, aber Sie haben vielleicht ein Missverständnis. Das 'waitpid' kehrt sofort zurück, wenn das Kind bereits gestorben ist; Andernfalls blockiert es, bis das Kind stirbt. Es sei denn, Sie verwenden WNOHANG mit dem waitpid, in diesem Fall wird es nicht blockieren, aber das ist hier nicht in Frage. – Duck

+0

Korrigieren Sie mich, wenn ich falsch liege, aber ich denke, dass der dritte Parameter (Null) WHOHANG entspricht. Wie auch immer, nehmen wir an, es war WHOHANG. Würde dann ein Zombie erstellt werden und wie? Und schließlich, sollte der waitpid der letzte Befehl sein, bevor 0 zurückgegeben wird; um sicherzustellen, dass keine Zombies erstellt werden ?. Danke noch einmal! – mgus

+1

Nein WNOHANG ist definitiv nicht gleich Null. Zero ist der Standardwert und es würde keinen Sinn ergeben, bitweise - oder WNOHANG, wenn es gleich 0 war. Wenn das Kind nach einem nicht blockierenden 'waitpid' starb und das Elternteil zuerst austrat, dann Sie Ich hätte einen Zombie. Normalerweise würden Sie jedoch eine nicht blockierende 'waitpid' in einer Schleife und möglicherweise in Verbindung mit dem Empfang von SIGCHLD verwenden. Waitpid selbst kann überall im Code sein, solange es Ihre Kinder behandelt, wenn es dazu aufgefordert wird. – Duck

Antwort

6

Das Kind wird nur ein Zombie, wenn es endet und die Eltern nicht wait*() ruft solange selbst lebt.

Im Moment der Eltern auch das Kind durch den init Prozess geerntet wird beendet, die darauf achten, werden wait*() auf dem Kind zu rufen, so wird es schließlich mit diesem Zweck und den Zombie-Zustand verlassen und verschwindet aus der Prozessliste.

Um das Kind in Ihrem Beispielcode erstellt provozieren werden ein Zombie, den Code zum Beispiel wie folgt ändern:

#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; 
} 

Durch die beiden folgenden Tatsachen:

  • das Kind für 3s schläft so wird der Aufruf der Eltern an waitpid() höchstwahrscheinlich immer
  • die Standardbehandlung von SIGCHLD ist es zu ignorieren.

der obige Code in der Tat ist die gleiche wie:

#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

Was ist in diesem Code, der verhindert, dass das Kind ein Zombie wird? Können Sie genauer erklären, warum Sie Schlaf- und Pausebefehle verwendet haben? Sorry für so viele Fragen, aber ich bin nicht mit diesen Begriffen vertraut. – mgus

+0

@Konstantinos Konstantinidis: "* Was verhindert dieser Code, dass das Kind ein Zombie wird? *" Nichts. Wie in meiner Antwort erwähnt, erzeugt dieser Code ** ** einen Zombie. – alk

0

ich einen einfachen Weg gefunden, einen Zombie-Prozess zu erstellen und testen ps -en

#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); 
    } 
} 

laufen ps - e während der 15 Sekunden ... werden Sie sehen

6454 Punkte/2 00:00:00 a.out < verstorben>