Dean Leitersdorf Dean Leitersdorf - 1 year ago 73
C Question

Trying to understand more on fork() in c

I am running the following code which I wrote in c on my Mac.

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

int main(int argc, const char * argv[]) {

int i = 0;
printf("Starting pid:%d\n", getpid());
int ret = fork();
printf("hello(%d)%d, %d ", i, getpid(), ret);
return 0;}

The goal I had in mind was for there to be 6 prints in total - 3 from the original parent (the pid printed in "Starting pid"), and 1 more from each of the 3 spawned children. Instead what I received was:

Starting pid:7998
hello(1)8009, 0
hello(1)7998, 8009 hello(2)8010, 0
hello(1)7998, 8009 hello(2)7998, 8010 hello(3)7998, 8011 hello(1)7998, 8009 hello(2)7998, 8010 hello(3)8011, 0

Note that the original parent (7998) prints 6 times (three times when i==1, twice with i==2, and once with i==3).

Why would this be happening? Why I am not receiving 3 prints from the parent (once when i==1, i==2, i==3). If we look at it from the parent's perspective - there is a while loop and we are supposed to hit the print statement inside only 3 times.

Is it perhaps that fork is async or something? What am I missing?

Answer Source

When you fork a process, the memory in parent is duplicated in the child. This includes the stdout buffer.

Starting on the second iteration of the loop in the parent, you have hello(1)7998, 8009 in the buffer. When the second child forks, this text is still in that child's buffer. The second child then prints hello(2)8010, 0, then a newline. The newline flushes the child's buffer, so the second child prints this:

hello(1)7998, 8009 hello(2)8010, 0 

After the fork, the parent prints hello(2)7998, 8010 which is added to the output buffer. Then on the third iteration, the third child inherits this and prints:

hello(1)7998, 8009 hello(2)7998, 8010 hello(3)8011, 0

The parent then prints hello(3)7998, 8011 which is again added to the buffer. Then parent then exits the loop and exits, after which the buffer is flushed and the parent outputs:

hello(1)7998, 8009 hello(2)7998, 8010 hello(3)7998, 8011

To correct this, then parent process needs to clear the output buffer before forking.

This can be done either by calling fflush(stdout) after calling printf, or by adding a newline (\n) to the end of the printf.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download