Как правильно завершить дочерний процесс? - PullRequest
0 голосов
/ 22 февраля 2019

В этом примере кода я ожидаю, что мои дочерние процессы завершатся нормально:

int main(void)
{
    for (int i = 0; i < 100; ++i)
    {
        int pid = fork();
        printf("pid %d\n", pid);
        sleep(1);
        if (pid == 0)
            exit(0);
    }
}

Но когда я запускаю ps, я получаю следующий вывод:

5089 pts/0    00:00:00 test
5090 pts/0    00:00:00 test <defunct>
5091 pts/0    00:00:00 test <defunct>
5092 pts/0    00:00:00 test <defunct>
5094 pts/0    00:00:00 test <defunct>

Чтоя должен сделать, чтобы дочерний процесс завершился нормально?

Ответы [ 3 ]

0 голосов
/ 22 февраля 2019

Если wait не вызван родителем, а потом дочерний элемент завершается - тогда он (дочерний элемент) остается зомби - бесконечно ожидая, когда будет получено его состояние выхода.И это тот случай, который происходит в вашем случае.

Если вы не хотите вызывать функцию wait у своего родителя, то вы должны создать своего ребенка как отдельный процесс.daemon() может помочь вам.http://man7.org/linux/man-pages/man3/daemon.3.html

0 голосов
/ 22 февраля 2019

Ваши процессы завершились нормально.<defunct> означает, что процесс мертв, и единственное, что осталось, это его PID и статус завершения.

Чтобы очистить эти <defunct> записи в таблице процессов, родительский процесс должен либо wait() дляего дети или выход сам.В последнем случае (родительский процесс умирает) дочерние процессы становятся сиротами и принимаются init (процесс с PID 1), который очищается после них.

В некоторых системах 1 Вы также можете игнорировать сигнал SIGCHLD:

signal(SIGCHLD, SIG_IGN);

Это означает, что дочерние процессы будут запущены немедленно.


1 POSIX перечисляет эту функцию как расширение XSI.Хотя это и не требуется для соответствия POSIX, оно будет поддерживаться всеми XSI-соответствующими системами.

0 голосов
/ 22 февраля 2019

Родительский процесс должен вызвать одну из функций wait (wait, waitpid, waitid, wait4), чтобы освободить ресурсы дочернего процесса.См. Тогда справочную страницу waitpid:

WAIT(2)

NAME
       wait, waitpid, waitid - wait for process to change state

SYNOPSIS
       #include <sys/types.h>
       #include <sys/wait.h>

       pid_t wait(int *wstatus);

       pid_t waitpid(pid_t pid, int *wstatus, int options);

       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
                       /* This is the glibc and POSIX interface; see
                          NOTES for information on the raw system call. */

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       waitid():
           Since glibc 2.26: _XOPEN_SOURCE >= 500 ||
               _POSIX_C_SOURCE >= 200809L
           Glibc 2.25 and earlier:
               _XOPEN_SOURCE
                   || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
                   || /* Glibc versions <= 2.19: */ _BSD_SOURCE

DESCRIPTION

…

       In the case of a terminated child, performing a wait
       allows the system to release the resources associated with the child;
       if a wait is not performed, then the terminated child remains in a
       "zombie" state (see NOTES below).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...