How is fork() working when children fork?

2019-04-11 12:38发布

问题:

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?

回答1:

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.



回答2:

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();
}


回答3:

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.



回答4:

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.



标签: c unix fork wait