Gadheyan .t.s
Gadheyan .t.s

Reputation: 407

confusing behaviour of fork() system call in c

I was checking behaviour of fork system call. I executed the following program.

#include<stdio.h>
int count=0;
int main()
{
int i;
int n=3;
for(i=1;i<=n;++i)
{
printf(" %d ",i);
fork();
} 
}

I had a thought that having fork() inside a for loop is similar to writing it in series i.e.

for(i=1;i<=3;i++)
   fork();

is similar to

fork();
fork();
fork();

I tried to draw a recursion tree for the same enter image description here

I expected the output to be eight consecutive 3's. But output was following:

 1  2  3  1  2  3  1  2  3  1  2  3  1  2  3  1  2  3  1  2  3  1  2  3

Note:compiled and executed in gcc

Upvotes: 0

Views: 233

Answers (4)

dvhh
dvhh

Reputation: 4750

because stdout output is buffered by default, forking the process will cause to duplicate the buffer and when each process is finished each buffer will be flushed.

using :

fprintf(stderr," %d ",i);

will make the program output :

1 2 2 3 3 3 3

because you are making the printf statement in the loop ( from 1 to 3 )

the following statement would help you trace the output :

fprintf(stderr," %d:%d ",i,getpid());

which will output (example) :

1:24100  2:24100  2:24101  3:24100  3:24102  3:24101  3:24103

Upvotes: 1

Govind Madhu
Govind Madhu

Reputation: 192

This questions has been asked before. You can find the similar question here.

Visually what happens to fork() in a For Loop

I hope that helps^^

Upvotes: 1

WhozCraig
WhozCraig

Reputation: 66194

First, your expectations are wrong, you will get more than just 3's output. Second, your stdout line buffer is retained when you fork, and thus will copy previously printf-ed content to the forked processes as part of the process duplicate. A modified version of your program below:

#include <stdio.h>
#include <unistd.h>
int main()
{
    int i;
    for(i=1;i<=3;++i)
    {
        printf("%d ", i);
        fflush(stdout);
        fork();
    }
}

will produce output similar to the following:

1 2 3 2 3 3 3 

The added flush empties the current-process' stdout line prior to the fork, thereby eliminating replicated output. The order may be slightly different, but will always start with 1, end with 3, Further, any 1 will always be followed by at least one 2, and any 2 always followed by at least one 3

Upvotes: 2

kishor
kishor

Reputation: 221

It will print like that
1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
because 1 time for parent and 1 time for child. Fork() :- for parent and child.

So loop is rotating 4 times thats

1 2 3 for parent 1 2 3 for child

2(Parent and child) * 4(Loop rotate) = it will print 8 times (1 2 3)

Upvotes: 1

Related Questions