Salil Salil - 3 months ago 30
C Question

fork() behavior in linux

I was trying to understand forks, and tried following in C:

#include<stdio.h>
#include <unistd.h>

void forker()
{
printf("%d: A\n",(int)getpid());
fork();
wait();
printf("%d: B\n",(int)getpid());
printf("%d: C\n",(int)getpid());
fork();
wait();
printf("%d: D\n",(int)getpid());
}

int main(void)
{
forker();
return 0;
}


When I compiled and ran resultant a.out, here is what I observed:

> ./a.out
3560: A
3561: B
3561: C
3562: D
3561: D
3560: B
3560: C
3563: D
3560: D


However when I do the following:

> ./a.out > t.txt


something weird happens:

> cat t.txt
3564: A
3565: B
3565: C
3566: D
3564: A
3565: B
3565: C
3565: D
3564: A
3564: B
3564: C
3567: D
3564: A
3564: B
3564: C
3564: D


Can someone please explain this behavior? Why is the output different when it is redirected to a file?

I am using Ubuntu 10.10, gcc version 4.4.5.

mah mah
Answer

The reason this happens is data buffering. At the time of the fork(), in the case of directing to a file, your output has not been flushed yet... so both the parent and the child now have outstanding output buffers.

Put a call to fflush(stdout); before each fork(); to resolve this.