Question

I know fork(), wait(), waitpid(), zombie processes... I understood them by reading W. Richard Stevens which is a very good book.

If we don't call wait() in parent the child becomes a zombie after termination... which is bad!

If we call wait() in parent then parent waits for child to terminate, receives the termination status and then continues. Write?

I have gone through many examples that call fork() once and then wait() in parent.

But if at all parent is going to wait for child and continue after the child terminates, then there is no actual multitasking going on(technically yes there are 2 processes. But logically of no use) then why did we call fork() here?

We could have written child's code and then parent's code instead of fork() & wait() as a single process...wouldn't it be better?

Thanks!

Was it helpful?

Solution

Sometimes, it is useful to fork() even if the parent is immediately going to block. The most common case is when you are doing something akin to the system() call, executing an external command and waiting for it to complete: you will do fork() + execve(). (Though, in modern code, you should consider using posix_spawn() instead for this purpose.)

Nevertheless, wait() does not need to block. You can use waitpid() with flag WNOHANG to collect exit code of any completed process or continuing immediately if it is still running.

OTHER TIPS

The code which you write inbetween fork() and waitpid() runs simultaniously, alongside child fork.

The parent waits until child finishes, often simply to pick up data delivered from child and hereby expose it to parent. Suppose you run a main loop where tasks are run as 'background'. For instance:

// a simple scheduler
while(1) {
   if(done_task_1) {
      // if done_task_1 is ever to change in the parent memory scope,
      // parent must know the exit status of its child fork.
      // otherwise there is no way to enter this if sentance, ever
      collect_data_1();
      run_task_1 = 0;
   }
   else if(run_task_1 == 1) {
      // iterate instructions for a sec
      posix_kill(pid_task_1, SIGCONT);
      sleep(1);
      posix_kill(pid_task_1, SIGSTOP);

   } 

   if(done_task_2) {
      collect_data_2();
      run_task_2 = 0;
   }
   else if(run_task_2 == 1) {
      // iterate instructions for a sec
      posix_kill(pid_task_2, SIGCONT);
      sleep(1);
      posix_kill(pid_task_2, SIGSTOP);

   } 
   if(run_task_1 == 0 && run_task_2 == 0) {
       break;
   }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top