Possible Duplicate:
fork() and output
by running:
#include<stdio.h>
int main()
{
fork();
printf("b");
if (fork() == 0) {
write(1, "a", 1);
}else{
write(1, "c", 1);
}
return 0;
}
I got cbcabbab
, could someone explain the output to me? And if possible, is there a tool to see the running procedure step by step?
Try running it again, you'll probably get a different output.
As for a tool to see the procedure step by step, I think
strace -f
might help a bit:Short answer: don't mix buffered and unbuffered code.
Long answer: let's test variants of your source code using the following commands:
This executes
program
a thousand times, and lists all unique outputs it returned.Buffered version: replace
write
byfwrite
(orprintf
)This gives a very regular pattern of output. In fact, only six outputs are possible:
What is going on?
"b"
to thestdout
stream. The stream is buffered by default, so .stdout
streams of W and X have the same state, so also the same buffer containing just"b"
. The same holds for Y and Z.stdout
stream.main
returns, the C runtime takes over. Every process flushes their buffers, including the buffers ofstdout
.Unbuffered version: replace
printf
bywrite
The possible output is now a little more varied, but it's still pretty understandable, given concurrency:
This is probably the output you expected.
Mixed version (yours)
Your code gives many more results than the previous two variants:
This is because the
write
call will produce output immediately, but the buffered"b"
will only be printed when each process terminates, which is after thewrite
call, of course. Just like in the fully buffered version, every process will have that"b"
in thestdout
buffer, so you'll end up seeing four of them.Unless you specifically add code to synchronize your forked processes, they will run completely independently, and thus the order of output is completely "random". The process scheduling will decide who gets to run next, which in turn depends on how many processor cores there are in the system, what else is running, and how long each process that is currently running has been running for.
As explained in the link, you also get output from the internal buffers of
printf
, since the output has not yet been written to the actual file representing thestdout
- you can "fix" that by adding afflush(stdout);
afterprintf
.