Papes Traore
Papes Traore

Reputation: 1

Understanding how UNIX fork() affects parent process

I have the following program that uses the fork() function to create child processes

#include <stdio.h>
   int main (){
   printf("PID:%d\n",getpid());//print1:P1
   fork();
   fork();
   fork();
   printf ("Done"); //print2:P2
}

I am trying to understand how does the above program prints 'Done' 8 times because that the output.

Upvotes: 0

Views: 209

Answers (3)

Nicholas Pipitone
Nicholas Pipitone

Reputation: 4142

I'll make it a bit more visual:

Step 1

// Program 1
#include <stdio.h>
   int main (){
   printf("PID:%d\n",getpid());//print1:P1
   fork(); // <- Current Line
   fork();
   fork();
   printf ("Done"); //print2:P2
}

Step 2

When this line executes, it splits into two programs:

// Program 1                                                   >----|
#include <stdio.h>                                                  |
   int main (){                                                     |
   printf("PID:%d\n",getpid());//print1:P1                          |
   fork(); // Returns child's PID [Program 1 Version 2]             |
   fork(); // <- Current line                                       |
   fork();                                                          |
   printf ("Done"); //print2:P2                                     |
}                                                                   |
                                                                    |
// Program 1 Version 2 (Child of Program 1)   >----|                |
#include <stdio.h>                                 |                |
   int main (){                                    |                |
   printf("PID:%d\n",getpid());//print1:P1         |                |
   fork(); // Returns 0, since it's a child        |                |
   fork(); // <- Current line                      |                |
   fork();                                         |                |
   printf ("Done"); //print2:P2                    |                |
}                                                  |                |

Step 3

When Program 1 Version 2 executes its current line, it creates

// Program 1 Version 2                       <-----|                |
#include <stdio.h>                                 |                |
   int main (){                                    |                |
   printf("PID:%d\n",getpid());//print1:P1         |                |
   fork();                                         |                |
   fork(); // Returns child's PID [Program 1 Version 2] Version 2   |
   fork(); // <- Current line                      |                |
   printf ("Done"); //print2:P2                    |                |
}                                                  |                |
                                              v----|                |
// [Program 1 Version 2] Version 2 (Child of Program 1 Version 2)   |
#include <stdio.h>                                                  |
   int main (){                                                     |
   printf("PID:%d\n",getpid());//print1:P1                          |
   fork();                                                          |
   fork(); // Returns 0 (It's a new child)                          |
   fork(); // <- Current line                                       |
   printf ("Done"); //print2:P2                                     |
}                                                                   |

When Program 1 executes its current line, it creates

// Program 1                                           <------------|
#include <stdio.h>                                                  |
   int main (){                                                     |
   printf("PID:%d\n",getpid());//print1:P1                          |
   fork();                                                          |
   fork(); // Returns child's PID [Program 1 Version 3]             |
   fork(); // <- Current line                                       |
   printf ("Done"); //print2:P2                                     |
}                                                                   |
                                                                    |
// Program 1 Version 3 (Child of Program 1)             <-----------|
#include <stdio.h>
   int main (){
   printf("PID:%d\n",getpid());//print1:P1
   fork();
   fork(); // Returns 0 (Is a new child)
   fork(); // <- Current line
   printf ("Done"); //print2:P2
}

Step 4

Each of the final forks again duplicates each program, leaving you with 8 programs running. Each original program gets the child's PID as returned by fork. Each child program gets 0. Then they all printf("Done")

Note

Once a program is generated, it just runs all the forks and gets a bunch of PIDs, then prints done. It just happens that each fork makes a child, but the parent doesn't notice and they're basically NO-OPs for the parent.

Upvotes: 0

Eugene Sh.
Eugene Sh.

Reputation: 18299

You should note that each subsequent fork will get executed by children that created before. So the process hierarchy will be as follows:

Parent
  -- Child 1                   (first fork executed by Parent)
     -- Grandchild 1           (second fork executed by Child 1)
        -- Grand-grandchild 1  (third fork executed by Grandchild 1)
     -- Grandchild 2           (third fork executed by Child 1)
  -- Child 2                   (second fork executed by Parent)
     -- Grandchild 3           (third fork executed by Child 2)
  -- Child 3                   (third fork executed by Parent)

And each of these will call printf ("Done");. 8 in total.

Upvotes: 3

Achal
Achal

Reputation: 11921

When a process is created by calling fork() like

 fork();

After fork() whatever statements are there, once they executed by child & once by parent process. In your case fork() is called thrice hence it print 8 times Done. It looks like

fork();
printf ("Done\n"); /* once printed by child process & once by parent process, so for one fork() call, it prints 2 times Done. For 3 fork call, 8 times */

From the manual page of fork()

fork() creates a new process by duplicating the calling process. The new process, referred to as the child, is an exact duplicate of the calling process

Upvotes: 1

Related Questions