Consider the following piece of code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i = 0; i < 2; i++)
{
fork();
printf(".");
}
return 0;
}
This program outputs 8 dots. How can that be possible? Should not there be 6 dots instead?
You have uncommitted buffers in the output streams. stdout is line-buffered, and the buffer is replicated together with the rest of the process. When the program terminates, the uncommitted buffer is written twice (once for each process). Both using
and
don't exhibit the problem.
In your first example, you create four processes which have each two dots in their output stream buffer. When each stream terminates, it flushes its buffer, generating eight dots.
when i=0
Process_1: Buffered text= 1 dot
Process_2(created by Process_1): Buffered text= 1 dot
when i=1
Process_3(created by Process_1): Inherit 1 buffered dot from Process_1 and prints 1 dot by itself. In total Process_3 prints 2 dots.
Process_4(created by Process_2): Inherit 1 buffered dot from Process_2 and prints 1 dot by itself. In total Process_4 prints 2 dots.
Process_1 : Prints 2 dots (One buffered dot when i=0 and another dot when i=1)
Process_2 : Prints 2 dots (One buffered dot when i=0 and another dot when i=1)
Final Output: 8 dots. :)
The
fork()
primitive often stretches the imagination. Until you get a feel for it, you should trace out on paper what each operation is and account for the number of processes. Don't forget that fork() creates a near-perfect copy of the current process. The most significant difference (for most purposes) is thatfork()
's return value differs between parent and child. (Since this code ignores the return value, it makes no difference.)So, at first, there is one process. That creates a second process, both of which print a dot and loop. On their second iteration, each creates another copy, so there are four processes print a dot, and then exit. So we can easily account for six dots, like you expect.
However, what
printf()
really does is buffer its output. So the first dot from when there were only two processes does not appear when written. Those dots remain in the buffer—which is duplicated at fork(). It is not until the process is about to exit that the buffered dot appears. Four processes printing a buffered dot, plus the new one gives 8 dots.If you wanted to avoid that behavior, call
fflush(stdout);
afterprintf()
.