2013-12-15 3 views
5

мне интересно, если следующий код может создать зомби:Может ли этот C-код создавать процессы зомби?

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

Таким образом, родительский процесс вызывает waitpid для дочернего процесса, который возвращается немедленно, если ребенок еще не вышел. Таким образом, до сих пор зомби не могут возникнуть. Но, если ребенок выйдет до

return 0;
, то это будет зомби? Я на самом деле смущен. Должна ли waitpid быть последняя строка кода до того, как программа завершится? Любая помощь будет оценена по достоинству. Благодаря!

+1

Это выглядит нормально, но у вас может быть недоразумение. «Waitpid» немедленно вернется, если ребенок уже умер; иначе он будет блокироваться до тех пор, пока ребенок не умрет. Если вы не используете WNOHANG с waitpid, в этом случае он не будет блокироваться, но это не проблема. – Duck

+0

Исправьте меня, если я ошибаюсь, но я думаю, что третий параметр (ноль) эквивалентен WHOHANG. В любом случае, давайте предположим, что это КТО ХОРОШО. Тогда будет создан зомби и как? И, наконец, если waitpid будет последней командой перед возвратом 0; чтобы не было создано никаких зомби ?. Еще раз спасибо! – mgus

+1

Нет. WNOHANG определенно не эквивалентен 0. Zero является значением по умолчанию, и это не имеет смысла для поразрядного - или WNOHANG, если оно равно 0. Если ребенок умер после неблокирующего «waitpid», а родительский вышел первым, то вы будет зомби. Но обычно вы должны использовать неблокирующий «waitpid» в цикле и, возможно, в сочетании с получением SIGCHLD. Сам Waitpid может быть где угодно в коде, если он обращается с вашими детьми, когда этого требуют. – Duck

ответ

6

Ребенок становится только зомби, если он заканчивается и родитель не вызывает wait*(), пока сам живет.

В настоящее время родитель также заканчивается ребенок пожинается процесс init который будет заботиться, чтобы позвонить wait*() на ребенка, поэтому он будет, наконец, закончится, и с этим выходить из состояния зомби и исчезает из списка процессов.

Чтобы спровоцировать ребенка, созданный в вашем примере кода, чтобы стать зомби изменения кода, например, следующим образом:

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

Из-за двух следующих фактов:

  • ребенок спит в течение 3 секунд поэтому запрос родителя на waitpid(), скорее всего, всегда будет сбой
  • Обработка по умолчанию SIGCHLD - это его игнорировать.

выше на самом деле код такой же, как:

#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

Что в этом коде, что мешает ребенку стать зомби? Можете ли вы объяснить более подробно, почему вы использовали команды ожидания и паузы? Извините за столько вопросов, но я не знаком с этими понятиями. – mgus

+0

@ Konstantinos Konstantinidis: «* Что в этом коде, что мешает ребенку стать зомби?» «Ничего. Как указано в моем ответе, этот код ** делает ** создание зомби. – alk

0

Я нашел простой способ создать процесс зомби и протестировать его с помощью пса -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); 
    } 
} 

пробега пса - е в течение 15 секунд ... вы увидите

6454 pts/2 00:00:00 a.out < несуществующий>

Смежные вопросы