Zombie process and fork

2.9k views Asked by At

i have a code like this...

c = fork();
if(c==0) {
    close(fd[READ]);

    if (dup2(fd[WRITE],STDOUT_FILENO) != -1) 
        execlp("ssh", "ssh", host, "ls" , NULL);
    _exit(1);

}   
close(fd[WRITE]);

fd[READ] and fd[WRITE] are pipe file descriptors.

when i run it continuously, there are a lot of zombie processes when i use ps ax. How to rectify this? Is this because i am not using the parent to wait for the exit status of the child process...

3

There are 3 answers

0
Hasturkun On BEST ANSWER

If you have no intention to wait for your child processes, set the SIGCHLD handler to SIG_IGN to have the kernel automatically reap your children, eg.

signal(SIGCHLD, SIG_IGN);
0
Benoit Thiery On

Yes, the parent must wait for the child return status. You can do it asynchronously by catching SIGCHILD in the parent process and then call waitpid in the capture method.

0
Prashanth Reddy On

Yes, waitpid() should be called from parent. waitpid() will clean-up any child process of the parent process, which is currently in terminated state.

You can add below code to your program :

if(c>0)
{
while(1){ 
ret = waitpid(-1,&status,0);

if(ret>0){
if(WIFEXITED(status)){
   if(WEXITSTATUS(status) == 0){ 
       printf("child process terminated normally and successfully\n");
   }
   else{

       printf("child process terminated normally and unsuccessfully\n");
   }
 }
else{ 

       printf("child process terminated abnormally and unsuccessfully\n");
    }
}
if(ret<0) { 
     break; 
    }
  }
}

FYI : more on waitpid.

First parameter is set to -1 such that waitpid() will clean-up any child process of this parent process, which is currently in terminated state.The first parameter can also be +ve - in this case, waitpid() will cleanup only the specific child process.Most common use is to set first parameter to -1 also refer to manual page of waitpid(). Second parameter is used to extract the termination/exit status code of the child process - waitpid() system call API fills the status field when the system call API is invoked. Last field is the flags field - currently unused - in most cases, flags field will be set to 0 - meaning, default behaviour of the system call API !!! if you really need to use flags, refer to manual page of waitpid().

Note: In the code you submitted, _exit(1) will be called iff execlp() fails. so you can put a condition for execlp() fail and that condition _exit() can be called. The Reason is, execlp() functions only return if an error has occurred.

Modified code can be like below :

c = fork();
if(c==0) {
close(fd[READ]);

if (dup2(fd[WRITE],STDOUT_FILENO) != -1) 
    ret_execlp = execlp("ssh", "ssh", host, "ls" , NULL);
if(ret_execlp == -1 ) {
      printf("execlp is failed");
      _exit(1);
   }
}
close(fd[WRITE]);

I appreciate the above 2 answers. Wish this answer may give more clarity. Thank you.