12

I am trying to understand fork(), and so I put together the following example:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

void main()
{
   if(fork()==0)
   {
      printf("2");

      if(fork()==0)
      {
          printf("4");
      }
      else
      {
          printf("3");
      }
   } 
   else
   {
      printf("1");
   }
}

When I was tracing this on paper, I drew the following sketch:

enter image description here

So I believe the output should be 1234. However, when I run this code, the output is 12324. Why is that? Where is my mistake?

Update:

After reading the comments, it was suggested to do any of the following

  1. Add \n to each printf statement
  2. OR: Add fflush(stdout); after each printf statement
  3. OR: Add setbuf(stdout, NULL); <---- this is what I ended-up doing :)

After updating my code, the output was indeed 1234.

lucidgold
  • 4,432
  • 5
  • 31
  • 51
  • or http://stackoverflow.com/questions/17454610/fork-in-c-using-printf, http://stackoverflow.com/questions/9581787/why-does-this-code-print-two-times, http://stackoverflow.com/questions/3513242/working-of-fork-in-linux-gcc and some more ... – Martin R Nov 06 '14 at 19:02

2 Answers2

11

printf() output is usually line-buffered. So when you fork(), the new processes gets the copy of the buffer as well. When the process exits, the whole buffer is flushed (or anytime it's flushed in the code or whenever the buffer becomes full). Hence, you see a copy of printf's output one more time.

1) You can flush it after each printf() call by using fflush(stdout);

2) or using \n for example:

  printf("2\n");

Another way is to disable the buffering with:

setbuf(stdout, NULL);
P.P
  • 117,907
  • 20
  • 175
  • 238
6

Your analysis is almost correct. However, printf does not necessarily write immediately do file descriptor - output is buffered inside the process. The second process does fork after putting 2 in the buffer. Both second and third processes will have it in the buffer and print 2.

If you do printf("2\n") instead new line character will force printf to flush the buffer and you will see only one 2.

zch
  • 14,931
  • 2
  • 41
  • 49