When using fork()
, is it possible to ensure that the child process executes before the parent without using wait()
in the parent?
This is related to a homework problem in the Process API chapter of Operating Systems: Three Easy Pieces, a free online operating systems book.
The problem says:
- Write another program using
fork()
. The child process should print "hello"; the parent process should print "goodbye". You should try to ensure that the child process always prints first; can you do this without callingwait()
in the parent?
Here's my solution using wait()
:
#include <stdio.h>
#include <stdlib.h> // exit
#include <sys/wait.h> // wait
#include <unistd.h> // fork
int main(void) {
int f = fork();
if (f < 0) { // fork failed
fprintf(stderr, "fork failed\n");
exit(1);
} else if (f == 0) { // child
printf("hello\n");
} else { // parent
wait(NULL);
printf("goodbye\n");
}
}
After thinking about it, I decided the answer to the last question was "no, you can't", but then a later question seems to imply that you can:
- Now write a program that uses
wait()
to wait for the child process to finish in the parent. What doeswait()
return? What happens if you usewait()
in the child?
Am I interpreting the second question wrong? If not, how do you do what the first question asks? How can I make the child print first without using wait()
in the parent?
I hope this answer is not too late.
Minutes ago, I have emailed Remiz(this book's author), and got such a replay(extract some segments):
Without calling wait() is hard, and not really the main point. What you did -- learning about signals on your own -- is a good sign, showing you will seek out deeper knowledge. Good for you!
Later, you'll be able to use a shared memory segment, and either condition variables or semaphores, to solve this problem.
I can't see why second question would imply that answer is "yes" to the first.
Yes there is plenty of solutions to obtain what asked, but of course I suspect that all are not in the "spirit" of the problem/question where the focus in on fork/wait
primitives. The point is always to remember that you can't assume anything after a fork regarding the way processes ran relatively to each other.
To ensure the child process print first you need a kind of synchronization in between both processes, and there is a lot of system primitives that have a semantic of "communication" between processes (for example locks, semaphores, signals, etc). I doubt one of these is to be used her, as they are generally introduced slightly later in such a course.
Any other attempt only that will only rely on time assumption (like using sleep
or loops to "slow" down the parent, etc) can lead to failure, means that you will not be able to prove that it will always succeed. Even if testing would probably show you that it seems correct, most of the runs you would try will not have the bad characteristics that lead to failure. Remember that except in realtime OSes, scheduling is almost an approximation of fair concurrency.
NOTE:
As Jonathan Leffler commented, I also suppose that using other wait
-like primitives is forbidden (aka wait4
, waitpid
, etc) -- "spirit" argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With