Because you just do fork
but don't check the return value (for 0 to execute child code), you're forking more children than you think.
The parent also does the printf
and not just the child.
And, after the first loop, the first child also does a fork
so you have an unexpected grandchild.
It also acts like parent and child and both do a print.
So, you get six total prints from the loop.
And, because there is no exit
call in the children, they "fall through" and execute the parent code at the bottom.
So, you get four prints from the code after the loop.
And, you should loop on wait
because you fork
two children but only do a single wait
.
Adding some getpid
and getppid
calls can show what is really happening:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#define PRINT(_fmt) \
printf("%d/%d " _fmt,getpid(),getppid())
int
main(void)
{
int f;
setlinebuf(stdout);
for (int i = 0; i < 2; i++) {
fork();
PRINT("hello\n");
}
wait(NULL);
PRINT("world\n");
exit(0);
}
Here is the output:
242293/2809616 hello
242293/2809616 hello
242294/242293 hello
242294/242293 hello
242295/242293 hello
242295/242293 world
242296/242294 hello
242296/242294 world
242293/2809616 world
242294/2806078 world
Here is the corrected program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#define PRINT(_fmt) \
printf("%d/%d " _fmt,getpid(),getppid())
int
main(void)
{
int f;
setlinebuf(stdout);
for (int i = 0; i < 2; i++) {
if (fork() == 0) {
PRINT("hello\n");
exit(0);
}
}
while (wait(NULL) >= 0);
PRINT("world\n");
exit(0);
}
Here is the program output:
242316/242314 hello
242315/242314 hello
242314/2809616 world