Working of fork() in linux gcc [duplicate]

fork() creates a new process and the child process starts to execute from the current state of the parent process.

This is the thing I know about fork() in Linux.

So, accordingly the following code:

int main() {
  printf("Hi");
  fork();
  return 0;
}

needs to print "Hi" only once as per the above.

But on executing the above in Linux, compiled with gcc, it prints "Hi" twice.

Can someone explain to me what is happening actually on using fork() and if I have understood the working of fork() properly?


(Incorporating some explanation from a comment by user @Jack) When you print something to the "Standard Output" stdout (computer monitor usually, although you can redirect it to a file), it gets stored in temporary buffer initially.

Both sides of the fork inherit the unflushed buffer, so when each side of the fork hits the return statement and ends, it gets flushed twice.

Before you fork, you should fflush(stdout); which will flush the buffer so that the child doesn't inherit it.

stdout to the screen (as opposed to when you're redirecting it to a file) is actually buffered by line ends, so if you'd done printf("Hi\n"); you wouldn't have had this problem because it would have flushed the buffer itself.


printf("Hi"); doesn't actually immediately print the word "Hi" to your screen. What it does do is fill the stdout buffer with the word "Hi", which will then be shown once the buffer is 'flushed'. In this case, stdout is pointing to your monitor (assumedly). In that case, the buffer will be flushed when it is full, when you force it to flush, or (most commonly) when you print out a newline ("\n") character. Since the buffer is still full when fork() is called, both parent and child process inherit it and therefore they both will print out "Hi" when they flush the buffer. If you call fflush(stout); before calling fork it should work:

int main() {
  printf("Hi");
  fflush(stdout);
  fork();
  return 0;
}

Alternatively, as I said, if you include a newline in your printf it should work as well:

int main() {
  printf("Hi\n");
  fork();
  return 0;
}