简体   繁体   中英

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 ie

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

is similar to

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

I tried to draw a recursion tree for the same 在此处输入图片说明

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

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

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)

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^^

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM