1

Can somebody explain to me why these two similar codes (except for the \n position) result in different output:

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

int main()
{
    int pid, i=0;
    printf("Ready to fork\n");
    pid=fork();
    if (pid==0)
    {
        printf("Child starts\n");
        for (i=0; i<1000; i++);
        printf("Child ends\n");
    }
    else
    {
        wait(0);
        for (i=0; i<1000; i++);
        printf("Parent process ends\n");
    }
    return 1;
}

Output:

enter image description here

And this:

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

int main()
{
    int pid, i=0;
    printf("\nReady to fork %d", getpid());
    pid=fork();
    if (pid==0)
    {
        printf("\nChild starts %d",getpid());
        for (i=0; i<1000; i++);
        printf("\nChild ends %d", getpid());
    }
    else
    {
        wait(0);
        for (i=0; i<1000; i++);
        printf("\nParent process ends %d", getpid());
    }
    return 1;
}

Results in:

enter image description here

I really can’t find any satisfactory reason of why a simple change in the position of \n changes the output of the program at the level where the parent program seems to restart after fork execution completes.

Thank you in advance.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Soumyadeep Ghosh
  • 366
  • 5
  • 13

1 Answers1

2

Unless the program's output is redirected to a file, printf()ing \n results, by default, in flushing the user-space buffer that printf() internally uses.

Not flushing the buffer before fork() implies that the child process obtains a copy of the parent's process not-yet-flushed buffer. For that reason you see Ready to fork twice in the version that is not printing \n, since the call to printf() for printing Ready to fork is performed before the call to fork().

JFMR
  • 23,265
  • 4
  • 52
  • 76
  • 1
    That explains it. Thank you very much. – Soumyadeep Ghosh Mar 04 '18 at 13:49
  • A tiny bit of confusion... Is it the child gets the buffer data, or when the control returns to caller and finds "\n" it flushes the buffer ? – Soumyadeep Ghosh Mar 04 '18 at 14:09
  • The child always get a copy of the parent's buffer by `fork()`ing. The question is: Is this buffer empty or not? Well, if the buffer is flushed before the call to `fork()` it will be empty for sure. By calling `printf()` with a trailing `\n` the buffer is flushed (unless output is redirected or flushing policy is changed). The parent is doing so in your 1st case. – JFMR Mar 04 '18 at 14:12
  • Note that after the `fork()` both buffers (parent and child) are independent (i.e.: each process has its own copy), but it is at the moment of forking when the child gets a copy of the parent's buffer (i.e.: the child's buffer is initialized with the content of the parent's buffer at that moment). – JFMR Mar 04 '18 at 14:17