Рубрики

Зомби-процессы и их предотвращение

Пререквизиты: fork () в C , Zombie Process

Состояние зомби : когда процесс создается в UNIX с использованием системного вызова fork (), адресное пространство родительского процесса реплицируется. Если родительский процесс вызывает системный вызов wait (), то выполнение родительского процесса приостанавливается до тех пор, пока дочерний процесс не будет завершен. По окончании дочернего процесса генерируется сигнал «SIGCHLD», который доставляется ядру родителю. Родитель, получив SIGCHLD, получает статус ребенка из таблицы процессов. Даже если дочерний элемент завершен, в таблице процессов есть запись, соответствующая дочернему элементу, в котором хранится состояние. Когда родитель собирает статус, эта запись удаляется. Таким образом, все следы дочернего процесса удаляются из системы. Если родитель решает не ждать завершения дочернего процесса и выполняет свою последующую задачу, то при завершении дочернего процесса состояние выхода не читается. Следовательно, запись в таблице процессов остается даже после завершения дочернего процесса. Это состояние дочернего процесса известно как состояние зомби.

// AC программа для демонстрации работы
// fork () и обрабатываем записи таблицы.
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>

  

int main()

{

    int i;

    int pid = fork();

  

    if (pid == 0)

    {

        for (i=0; i<20; i++)

            printf("I am Child\n");

    }

    else

    {

        printf("I am Parent\n");

        while(1);

    }

}

Выход :

Теперь проверьте таблицу процессов, используя следующую команду в терминале

$ ps -eaf

Здесь запись defunct [a.out] показывает процесс зомби.

Почему мы должны предотвратить создание процесса зомби?
Для каждой системы существует одна таблица процессов. Размер таблицы процессов конечен. Если генерируется слишком много зомби-процессов, таблица процессов будет заполнена. То есть система не сможет генерировать какие-либо новые процессы, тогда система остановится. Следовательно, нам нужно предотвращать создание зомби-процессов.

Различные способы предотвращения создания Зомби

1. Использование системного вызова wait (): когда родительский процесс вызывает wait () после создания дочернего объекта, это означает, что он будет ожидать завершения дочернего процесса и получит статус выхода дочернего элемента. Родительский процесс приостанавливается (ожидает в очереди ожидания), пока дочерний процесс не будет завершен. Следует понимать, что в течение этого периода родительский процесс ничего не ждет.

// AC программа для демонстрации работы
// fork () / wait () и процессы Zombie
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>

  

int main()

{

    int i;

    int pid = fork();

    if (pid==0)

    {

        for (i=0; i<20; i++)

            printf("I am Child\n");

    }

    else

    {

        wait(NULL);

        printf("I am Parent\n");

        while(1);

    }

}

2. Игнорируя сигнал SIGCHLD: Когда дочерний процесс завершается, соответствующий сигнал SIGCHLD доставляется родителю, если мы называем «сигнал (SIGCHLD, SIG_IGN)», то сигнал SIGCHLD игнорируется системой, а дочерний запись процесса удаляется из таблицы процессов. Таким образом, зомби не создается. Однако в этом случае родитель не может знать о статусе выхода ребенка.

// AC программа для демонстрации игнорирования
// сигнал SIGCHLD для предотвращения процессов зомби
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>

  

int main()

{

    int i;

    int pid = fork();

    if (pid == 0)

        for (i=0; i<20; i++)

            printf("I am Child\n");

    else

    {

        signal(SIGCHLD,SIG_IGN);

        printf("I am Parent\n");

        while(1);

    }

}

3. Используя обработчик сигнала: родительский процесс устанавливает обработчик сигнала для сигнала SIGCHLD. Обработчик сигнала вызывает системный вызов wait () внутри него. В этом сенарио, когда ребенок прерывается, SIGCHLD доставляется родителю. При получении SIGCHLD соответствующий обработчик активируется, что, в свою очередь, вызывает системный вызов wait (). Следовательно, родительский объект собирает статус выхода почти сразу, а дочерняя запись в таблице процессов очищается. Таким образом, зомби не создается.

// AC программа для демонстрации обработки
// Сигнал SIGCHLD для предотвращения процессов зомби.
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>

  

void func(int signum)

{

    wait(NULL);

}

  

int main()

{

    int i;

    int pid = fork();

    if (pid == 0)

        for (i=0; i<20; i++)

            printf("I am Child\n");

    else

    {

        signal(SIGCHLD, func);

        printf("I am Parent\n");

        while(1);

    }

}

Выход:

Здесь не существует [a.out] не существовавшего, то есть никакой процесс Zombie не создается.

Эта статья предоставлена Кишлай Верма . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

Зомби-процессы и их предотвращение

0.00 (0%) 0 votes