Search code examples
cfork

How to exit child process correctly?


With this code example I expect that my child processes will exit normally:

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

But when I run ps, I get the following output:

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>

What should I do to make child process exit normally?


Solution

  • The parent process must call one of the wait functions (wait, waitpid, waitid, wait4), to release child process resources. See then manpage of 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).