Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fork() behavior in linux

Tags:

c

gcc

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.

like image 739
Salil Avatar asked Nov 24 '11 10:11

Salil


People also ask

What does fork () do in Linux?

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.

What happens when fork () is called?

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.

What is fork () and why is it used?

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.

How is fork implemented in Linux?

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.


2 Answers

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.

like image 181
mah Avatar answered Oct 20 '22 18:10

mah


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/

like image 3
Tudor Avatar answered Oct 20 '22 19:10

Tudor