Using waitpid to Reap Zombie Children

When a process terminates for any reason, the kernel does not remove it from the system immediately. Instead, the process is kept around in a terminated state until it is reaped by its parent. When the parent reaps the terminated child, the kernel passes the child's exit status to the parent, and then discards the terminated process, at which point it cease to exit. A terminated process that has not yet been reaped is called a zombie.

      A process waits for its children to terminate or stop by calling the waitpid function. The waitpid function suspends the execution of the calling process until a child process in its wait set terminates. If a process in the wait set has already terminated at the time of the cal, then waitpid function returns immediately. In either case, waitpid returns the PID of the terminated child that caused waitpid to return, and the terminated child is removed from the system.

      Here we are going to use waitpid function to reap zombie children both in no particular order and in the order they were created. First, consider the following code which reaping zombie children in no particular order.

#include "csapp.h"
const int N = 2;

int main()
{
    int status;
    pid_t pid;
    
	// Parent creates N children
    for (int i=0; i!=N; ++i)
        if ((pid=Fork()) == 0) // Child
            exit(100+i);

    // Parent reaps N children in no particular order
    while ((pid = waitpid(-1, &status, 0)) > 0) {
        if (WIFEXITED(status))
            printf("child %d terminated normally with exit status=%d\n",
                    pid, WEXITSTATUS(status));
        else
            printf("child %d terminated abnormally\n", pid);
    }
    
    // The only normal termination is if there are no more children
    if (errno != ECHILD)
        unix_error("waitpid error");

    exit(0);
}
The program reaps its children in no particular order. The order that they were reaped is a property of this specific computer system. On another system, or even another execution on the same system, the two children might have been reaped in the opposite order.

      A simple change that eliminates this nondeterminism in the output order by reaping the children in the same order that they were created by the parent is presented below.

#include "csapp.h"
const int N = 2;

int main()
{
    int status;
    pid_t pid[N], retpid;
    
	// Parent creates N children
    for (int i=0; i!=N; ++i)
        if ((pid[i]=Fork()) == 0) // Child
            exit(100+i);

    // Parent reaps N children in no particular order
    int i = 0;
    while ((retpid = waitpid(pid[i++], &status, 0)) > 0) {
        if (WIFEXITED(status))
            printf("child %d terminated normally with exit status=%d\n",
                    pid, WEXITSTATUS(status));
        else
            printf("child %d terminated abnormally\n", pid);
    }
    
    // The only normal termination is if there are no more children
    if (errno != ECHILD)
        unix_error("waitpid error");

    exit(0);
}

      The essay ends with a conclusion, which we presented two examples of using the waitpid function to wait, both in no particular order and in the order children were created, for all of its N children to terminate.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章