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.
In the computing field, fork() is the primary method of process creation on Unix-like operating systems. This function creates a new copy called the child out of the original process, that is called the parent. When the parent process closes or crashes for some reason, it also kills the child process.
When a process calls fork, it is deemed the parent process and the newly created process is its child. After the fork, both processes not only run the same program, but they resume execution as though both had called the system call.
fork() is how you create new processes in Unix. When you call fork , you're creating a copy of your own process that has its own address space. This allows multiple tasks to run independently of one another as though they each had the full memory of the machine to themselves.
Under Linux, fork() is implemented using copy-on-write pages, so the only penalty that it incurs is the time and memory required to duplicate the parent's page tables, and to create a unique task structure for the child.
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.
The problem is that the output of printf
is passed through a library buffer before being sent to the file, which causes the strange behavior you mentioned. If you add a fflush(stdout)
after each printf
your output will be correct also inside the file.
You can read more about this here: http://www.pixelbeat.org/programming/stdio_buffering/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With