Search code examples
coperating-systemfork

What portion of code is executed by child process when fork() is called?


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

int main() {
   int pid;
   int pids[3];
   int status;
   int numprocesses = 0;
   int total_processes = 3;
   while (numprocesses < total_processes) {
      pid = fork();
      
      // Child process
      if (pid == 0) {
         printf("In child process: process id is %d\n", getpid());
         sleep(5);
         return 4;
      } else {
         pids[numprocesses] = pid;
         numprocesses++;
         printf("In parent process: created process number: %d\n", pid);
      }
   }
   printf("Checking\n");
   
   // Waiting for 3rd child process
   waitpid(pids[total_processes - 1], &status, 0);
   if (WIFEXITED(status) != 0) {
      printf("process %d exited normally\n", pids[total_processes - 1]);
      printf("exit status from child is %d\n", WEXITSTATUS(status));
   } else {
      printf("process %d not exited normally\n", pids[total_processes - 1]);
   }
   return 0;
}

My expectation was 'Checking' string should have been printed from parent as well as child process. But 'Checking' string is printed only once.

Does that mean only the code present in if (pid == 0) {..} will be executed by the child process?


Solution

  • My expectation was 'Checking' string should have been printed from parent as well as child process. But 'Checking' string is printed only once.

    The code you post has this child specific code:

          // Child process
          if (pid == 0) {
             printf("In child process: process id is %d\n", getpid());
             sleep(5);
             return 4;
          } else {
          ...
    

    and the final return 4; statemente makes the child to return from main() and not executing the part after the while loop.

    This, indeed, saves you from something... this is, all the children of your single parent make a return 4; and your parent should do as many wait() calls to wait for all the children. If any child had got out of the loop, as they have made no fork() they would have return from wait with an error (errno == ECHILD) indicating that no child has been created and is to be waited for.

    So, the thing is that the only process that gets out of the loop is the parent of all child processes created in the loop. So only one Checking should be expected, because only one process executes it.

    If, instead of return 4; you should have break; the loop, then you should have one Checking per child, with erroneous call to wait, and one more for the parent, with only one child notified (which one is unpredictable, most probably the first that exit(2)s)