Reputation: 81
Why program prints 4 times 'do' instead of just one 'do'?
Code:
#include<stdio.h>
#include<unistd.h>
int main()
{
printf(" do ");
if(fork()!=0) printf(" ma ");
if(fork()==0) printf(" to \n ");
else printf("\n");
}
Program prints do ma do do ma to do to
Upvotes: 0
Views: 71
Reputation: 629
You call fork twice in your "if" statements:
if(fork()!=0) printf(" ma ");
if(fork()==0) printf(" to \n ");
On the first fork, the parent A spawns a child B, then both the parent and child will invoke the fork a second time. The parent will spawn child C and the child will spawn child D. The result are 4 processes: A,B,C,D.
A ---- B
| |
C D
Since your prints are buffered until flushed to stdout and each forked process gets a copy of this buffer, four "do" are printed (check @ilkkachu answer).
If you intend to have a single "do", you should do this instead:
pid_t pid = fork();
if (pid > 0){
printf(" do ");
printf(" ma ");
} else {
printf(" to \n");
}
Basically store the return of fork() in a variable instead of invoking fork twice in your "if" statements.
Upvotes: 2
Reputation: 6527
Because standard output is line-buffered by default (or fully buffered, if you redirect it to a file or a pipe).
The first printf
doesn't hit a newline, so it only adds the string do
to a buffer internal to the C library. On the first fork
, the whole process, including that buffer, is duplicated. Then one of the copies adds ma
to its buffer, and both copies are duplicated (since both processes call fork
again, not just the parent or the child.)
Finally, either printf(" to \n ")
or printf("\n")
is called, producing a newline, which triggers the actual writing of whatever was in the buffer.
You can either use fflush(stdout)
to force the C library to output any buffered data before you fork, or use setbuf(stdout, NULL)
to disable buffering completely.
Upvotes: 1