cmultithreading

Wait for child process without using wait()


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:

  1. 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 calling wait() 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:

  1. Now write a program that uses wait() to wait for the child process to finish in the parent. What does wait() return? What happens if you use wait() 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?


Solution

  • Create a pipe in the parent. After fork, close the write half in the parent and the read half in the child.

    Then, poll for readability. Since the child never writes to it, it will wait until the child (and all grandchildren, unless you take special care) no longer exists, at which time poll will give a "read with hangup" response. (Alternatively, you could actually communicate over the pipe).

    You should read about O_CLOEXEC. As a general rule, that flag should always be set unless you have a good reason to clear it.