2013-12-15 13 views
5

Zastanawiam się, czy następujący kod może stworzyć zombie:Czy ten kod C może tworzyć procesy zombie?

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

Więc proces nadrzędny wywołuje waitpid dla procesu potomnego, która zwraca natychmiast, jeśli dziecko nie zostało już zakończone. Tak więc do tej pory nie mogą powstać żadne zombie. Ale jeśli dziecko wyjdzie przed komendą

return 0;
, będzie to zombie? W rzeczywistości jestem zdezorientowany. Czy waitpid powinien być ostatnim wierszem kodu przed zakończeniem programu? Każda pomoc będzie doceniona. Dzięki!

+1

To wygląda dobrze, ale możesz mieć nieporozumienie. 'Waitpid' zwróci natychmiast, jeśli dziecko już umarło; w przeciwnym razie zablokuje się, dopóki dziecko nie umrze. O ile nie użyjesz WNOHANG z waitpidem, w takim przypadku nie będzie blokował, ale nie ma tu mowy. – Duck

+0

Popraw mnie, jeśli się mylę, ale myślę, że trzeci parametr (zero) jest równoważny WHOHANG. W każdym razie, załóżmy, że to było WHOHANG. Czy wtedy powstanie zombie i jak? I wreszcie, czy waitpid będzie ostatnim poleceniem przed powrotem 0; aby upewnić się, że żadne zombie nie zostaną stworzone ?. Dzięki jeszcze raz! – mgus

+1

No WNOHANG zdecydowanie nie jest równoważne 0. Zero jest domyślne i nie ma sensu bitwise - lub WNOHANG, jeśli było równe 0. Jeśli dziecko zmarło po niezablokowaniu 'waitpid', a rodzic wyszedł pierwszy, to miałbym zombie. Ale normalnie używałbyś nie blokującego 'waitpid' w pętli i prawdopodobnie w połączeniu z odbiorem SIGCHLD. Sam Waitpid może znajdować się w dowolnym miejscu kodu tak długo, jak obsługuje on twoje dzieci, gdy zostanie do tego wezwany. – Duck

Odpowiedz

6

Dziecko staje się tylko zombie, jeśli kończy się to i rodzic nie wymaga wait*()dopóki sam żyje.

W momencie, gdy rodzic także się kończy, dziecko jest odczytywane przez proces , który zajmie się wywołaniem na dziecku, więc w końcu się skończy, a to spowoduje zombie stan i zniknie z listy procesów.

sprowokować dziecko utworzony w przykładowym kodzie, aby stać się zombie zmodyfikować kod na przykład w następujący sposób:

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

Ze względu na dwa następujące fakty:

  • dziecko śpi 3s więc połączenie rodzica do waitpid() najprawdopodobniej zawsze zawiedzie
  • domyślną obsługą SIGCHLD jest zignorowanie go.

kod powyżej w rzeczywistości jest jak poniżej:

#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

Co jest w tym kodzie, który uniemożliwia dziecku stanie się zombie? Czy możesz dokładniej wyjaśnić, dlaczego użyłeś poleceń trybu uśpienia i wstrzymania? Przepraszamy za tak wiele pytań, ale nie znam tych pojęć. – mgus

+0

@Konstantinos Konstantinidis: "Co zawiera kod, który uniemożliwia dziecku stanie się zombie? *" Nic. Jak stwierdzono w mojej odpowiedzi, ten kod ** nie ** tworzy zombie. – alk

0

że ustalono prosty sposób stworzyć proces zombie i przetestować stosując 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); 
    } 
} 

prowadzony PS - e podczas gdy w ciągu 15 sekund ... zobaczysz

6454 pkt/2 00:00:00 a.out < nieistniejące>