Output of fork() calls

2020-02-10 10:31发布

问题:

What would be the output of following fork() calls ?

func(){
fork();
fork();
fork() && fork() || fork();
fork();
print("Saikacollection\n");
}

Can anyone help me in getting the answer to this code as well as some explanations as I am new to OS ? I have found several questions on fork() on SO, but couldn't figure out much.

回答1:

Saikacollection will be printed 40 times as output to the code. This can be explained as follows :-

To understand the output, we need to know following :-

  • On successful execution of a fork() call, new child is created. The process creating the child is called parent process.
  • Fork() call returns pid (process identifier) of the child to parent
  • Fork() returns 0 to the child process.

Consider the image shown :-

Convention : All the parents(callers) of the process are written to left and marked with a star.

fork()
  • At the beginning, we have just 1 process, so a fork() call creates a child. Considering the root of the tree as level 1, we can see at level 2 , we have two processes, parent(left) and child(right) .

    fork()

  • fork() again further creates 4 such processes, marked as 1, 2, 3, 4. Since all of the four processes will go through similar code structure further, we can say the total number of processes will be 4 times a single process produces

    fork()&&fork()||fork()

  • Understanding this statement involves, realizing the fact that in C, && operator has more precedence than ||

  • Also, if first of two operands joined by && goes wrong, we don't check the second. Similarly, if first of the two operands of || is true, we don't check the second operand.
  • Consider, the fork() call at 1(marked) node, two processes are created. While the parent gets a positive number(pid) as return, child gets a 0. So, parent executes the second operator, while the child jumps to fork() after || as marked in the figure.
  • The execution of &&fork() for the parent at 4th level, returns a pid for one process, which terminates, while the child of that step, gets a 0. So, it goes for execution of ||fork()
  • the final ||fork() call for child of level 5, further produces a process as a result
  • So, at the end of the step, we have 5 leaves(processes) as marked by underlines in the figure.
  • Had we done the same for all the three nodes, we could have got 5*4 = 20 processes.

    fork()

  • Final fork() just doubles the number of process available at that step.

  • So, total number of processes = 2*20 = 40.


回答2:

Saikacollection is printed 32 times in a new line every time.



回答3:

If you want new process to be more independent, you might take a look at exec-* family of funcitons (POSIX) - so you can fork, and then immediately replace the fork process (you can do it, since newly forked process is controlled by you); Or possibly have a look at popen() as well.



标签: fork