I wrote a program that calls fork()
two times, generating three children and a parent.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
int child1 = fork();
int child2 = fork();
// Check for error
if (child1 < 0 || child2 < 0) {
fprintf(stderr, "A fork failed :(\n");
exit(1);
}
// Parent Process
if (child1 > 0 && child2 > 0) {
waitpid(child1, NULL, 0);
waitpid(child2, NULL, 0);
printf("I'm the parent\n");
}
// Child B -- CONFUSION AREA --
else if (child1 > 0 && child2 == 0) {
waitpid(child1, NULL, 0); // Not waiting for process to finish
printf("I'm child B\n");
}
// Child A
else if (child1 == 0 && child2 > 0) {
waitpid(child2, NULL, 0);
printf("I'm child A\n");
}
// Child C
else if (child1 == 0 && child2 == 0) {
printf("I'm child C\n");
}
return 0;
}
I'm trying to print out
I'm child C
I'm child A
I'm child B
I'm the parent
but instead, the program prints out
I'm child B
I'm child C
I'm child A
I'm the parent
I'm confused why child B isn't waiting for child1
process to finish?
I drew a process tree to try and understand what is going on, and my understanding is that it looks like:
/*
Parent (15543)
child1 = 15544;
child2 = 15545
/ \
/ \
/ \
A (15544) B (15545)
child1 = 0; child1 = 15544;
child2 = 15546; child2 = 0;
/
/
/
C (15546)
child1 = 0;
child2 = 0;
*/
CodePudding user response:
When child B calls waitpid()
the call fails and returns -1 because the parent is already waiting on child A, and you can't reap a child process twice.
For the behavior you want, you may be better off using inter-process semaphores to synchronize your process execution. Try including semaphore.h
and take a look at the documentation for sem_init()
.