wait() function in Ubuntu

Alfred James picture Alfred James · Sep 23, 2012 · Viewed 9.4k times · Source

I am learning Processes and their behavior in Ubuntu, but I am a bit confused in wait(). So my questions are:

  1. How the statment while(wait(NULL)>0); is working?
  2. What is the purpose of NULL in wait()?

I have seen the output in the terminal but the parent is executing and making children even when it executes the wait() function. Shouldn't the parent execution halt? Here is the code:

int main(int argc, char *argv[])
{
pid_t childid;

if(argc!=2)
{
    printf("Please provide an argument in terminal! \n");
    return 0;
}

int i,n=atoi(argv[1]);

for(i=0;i<n;i++)
{
    childid=fork();

    if(childid==0)
    {
        printf("Inside Child process! \n My id is %d\n",getpid());
        break; // creating fan process structure
    }
    else
        if(childid>0)
        {
            printf("Inside Parent Process! \n My id is %d\n",getpid());
        }
}

while(wait(NULL)>0); 

printf("After While Statment!\n My id is %d\n My parent ID is %d\n Child id is %d\n",getpid(),getppid(),childid);

}

I know this is a very lame question but this is the way people learn :)

Thanks

Answer

Tanmoy Bandyopadhyay picture Tanmoy Bandyopadhyay · Sep 23, 2012

How the statment while(wait(NULL)>0); is working?

The function wait, waits for the termination of any of the child process, and if successful, it returns the process identifier of the terminated child.If there is no child, it returns -1.

In your code the parent process basically waits for the termination of all the children it has created.

And for any of the children this call will immediately return -1, since they have not created any process.

What is the purpose of NULL in wait()? If you see the prototype of wait, it is like this,

pid_t wait(int *status);

The parent process can fetch the exit status, of a child process, in the variable status (We need to pass the address of an integer in the wait function, to update that integer) and then WEXITSTATUS macro to extract that value.

Passing NULL (we pass NULL since the variable is of pointer type) means, the programmer is not interested in that value and he is notifying this to the wait call.

I have slightly modified your code, to explain the return value of the wait function and the use of a non NULL argument. All the children are now returning a value(the loop index i), which is fetched by the parent.

Pl. see if this helps,

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>

int main(int argc, char *argv[])
{
  pid_t childid;
  int ret;
  int status;

 if(argc!=2)
 {
    printf("Please provide an argument in terminal! \n");
    return 0;
 }

int i,n=atoi(argv[1]);

for(i=0;i<n;i++)
{
  childid=fork();

  if(childid==0){
    printf("Inside Child process! \n My id is %d\n",getpid());
    break; // creating fan process structure
  }
  else if(childid > 0){
        printf("Inside Parent Process! \n My id is %d\n",getpid());
  }
}

//The line below, will be immediatly false for all  the children
while ((ret= wait(&status))>0)
{
  printf("After While My id is %d and my  child with pid =%d exiting with return value=%d\n" ,
  getpid(),ret, WEXITSTATUS(status));
}
//The if below will be true for the children only
if ((0 > ret) && (childid == 0)){
   printf("Child with id %d exiting and my parent's id is %d\n", getpid(), getppid());
   exit(i);
 }
else{
   printf("Parent Finally Exiting\n");
 }
}