3

I have executed a block of code. And it is as shown below:

#include<stdio.h>

main() {
int i=0;
fork();
printf("The value of i is:%d\n",++i);
fork();
printf("The value of j is:%d\n",++i);
fork();
wait();
}

And I got following output:

The value of i is:1
The value of j is:2
The value of i is:1
The value of j is:2
The value of j is:2
pckoders@ubuntu:~$ The value of j is:2

Can anyone explain to me what role fork() and wait() functions play here?

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
Babanna Duggani
  • 737
  • 2
  • 12
  • 34

4 Answers4

11

fork() call is a literally fork. After it's finished you are having 2 exact processes with exact stack and all descriptors are referring to same objects. You can distinguish them by a return value. For child process fork() returns 0, for parent - child's process id.

so

main() {
int i=0;
fork(); 
// at this point you are having 2 processes. stdout and stdin are basically just dupplicates.
//          (P)
//        /     \
//     (P)       (C)
//   prints1    prints 1
printf("The value of i is:%d\n",++i); // so 2 processes with print 1
fork();
// now you are having 4 processes( both parent and children forked)
//                   (P)
//                 /     \
//               /         \
//           (P)            (C)
//         /     \         /   \
//      (PP)     (PC)    (CP)  (CC)
//   prints 2  prints 2  prints 2  prints 2
printf("The value of j is:%d\n",++i);
fork();
// now 4 processes are forking. now you have 8 processes
//                                   (P)
//                                /       \
//                            /              \
//                         /                    \
//                   (P)                           (C)             
//                 /     \                       /     \           
//               /         \                   /         \          
//          (PP)           (PC)             (CP)          (CC) 
//         /     \        /     \          /    \       /     \        
//     (PPP)    (PPC)  (PCP)   (PCC)   (CPP)   (CPC)  (CCP)  (CCC)   

wait();
}
GreenScape
  • 7,191
  • 2
  • 34
  • 64
  • GreenScape , I am very happy with the way you explained the concept with such a neat diagram. I got it. Thanks for your concern and reply. But clear me one more doubt i.e, why it is printing value of i and j alternatively? After first fork(), immediately, it should display the value of i two times one after the other. But it is showing value of j after printing i's value once... – Babanna Duggani Sep 30 '11 at 13:29
  • That's totally depend's on OS's scheduler. Imagine process P forked into P and C. CPU working with P process. It prints 1. Goes to next fork. Performing it. Process PP prints 2. Scheduler switches to process C, now CPU work's with C. C prints 1. an so on... – GreenScape Sep 30 '11 at 13:42
  • What happens if there is no wait()? – jdyg Oct 25 '14 at 14:02
  • You would probably see completely different process tree. Instead of waiting each process will exit ASAP. It depends on which process has a chance to exit first. – GreenScape Oct 28 '14 at 09:14
6

The program generates a tree of processes. At every fork, this tree branches in two. If you grab a piece of paper, it's not very hard to draw this tree; the only thing that's hard is getting the i values right due to your use of prefix ++. If you let each of the process sleep for a few seconds at the end, you can also observe the tree using the pstree program.

Each one of the processes then runs the wait system call, which waits for any one of its child processes (child nodes in the process tree) to finish.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
1

After the first fork() there were two processes (the current and it's exact copy, the child), which both printed 1.

Each of these two processes duplicated itself with the second fork() call, and there were 4 processes, each of them printed 2.

Their output comes in random order, as it always does with parallel execution.

hamstergene
  • 24,039
  • 5
  • 57
  • 72
-1

The Forking processes creates Children in a tree-like manner.Consider each fork to be the different layers of a Binary Tree.When you dont issue a fork() u have a process tree of only a root node.When u issue a single fork() then u have a binary tree with two levels now , the first level will the contain the parent process , the second level will contain two processes - the parent and the child process.

When u want to find out the number of processes u have at hand just proceed building the binary/process tree and see how many nodes are there at the last level, the last level is nothing but the current state of the process/tree.Wait function makes your parent wait for the child process to finish executing.In applications where u do not want a zombie process you need to issue a wait or else these zombie processes will keep hogging the system... link.

Remember that wait is also useful when you always want the parent to finish after the child . Forking doesnt always give the same output , the order is jumbled , thus to get the same output always , use wait(). To wait on a particular child process , use wait(pid) where the pid is the pid of a specific child and that pid can be obtained by getpid inside the child process's space.

Community
  • 1
  • 1
  • 1
    –1 for all the ridiculous ellipses and the “u” silliness, and everything else that makes this an utterly unreadable non-answer. Rewrite in Standard English by using proper paragraphs, spelling, and punctuation, and this downvote will be removed. – tchrist Sep 09 '12 at 14:58