1

My textbook gives the following main routine:

int main()
{
if(fork() == 0)
    {
        printf("a");
    }
    else
    {
        printf("b");
        waitpid(-1, NULL, 0);
    }
    printf("c");
    exit(0);
}

It asks what the possible outputs are, and I have found 3:

abcc: The OS chooses the child process to execute first, and prints "a". Then, the OS pauses the child process and resumes the parent process, printing "b". Then the parent must wait until the child is done, and the child prints "c", and finally the parent prints "c".

bacc: The OS chooses the parent process to run first, and prints "b". Then the parent must wait for the child to complete and print "ac". Then the parent prints "c".

acbc: The OS chooses the child to run first until completion, printing "ac". Then the parent runs to completion, printing "bc".

However, there is one more answer listed in the textbook, bcac. I don't understand how this is possible because if b is printed first, then the parent must wait for the child to continue, and print "ac", then the parent would print "c", giving bacc which I've already listed. Is there something I'm missing, or is it correct to say there are only 3 possible outputs?

tomKPZ
  • 827
  • 1
  • 10
  • 17
  • Just like acbc, where the parent fork completes, and then the child fork completes, bcac is the child fork completing followed by the parent fork completing. bcac is a result of false (b) > outside conditional (c) > exit > true (a) > outside conditional (c) > exit – ciphermagi Dec 02 '13 at 18:20
  • I take it the cases where `fork` (or `printf`) fails are not to be taken into account? – Fred Foo Dec 02 '13 at 18:22
  • I think you are correct and the textbook wrong. `ac` of the child is always printed before `waitpid()` returns (`exit(3)` calls `fflush(2)` implicitly). As parent prints `c` after `waitpid`, the `ac` can not be at the end. – ensc Dec 02 '13 at 18:39
  • `bcac` is possible only if you assume that another child has terminated (which is demonstrably not the case, since we know only one is spawned!) or that the `write` call done by `printf` when the C library flushes its buffer at child exit is realized after the `write` call done by the `printf` in the parent process. Which is theoretically possible, but an extremely contrieved hypothetical sophistry. For any _reasonable_ thinking, it's impossible. – Damon Dec 02 '13 at 19:16
  • Assume the code for `printf()` ties itself to one thread, the parent. Now the parent will run, print `b`, then wait on the child. The child sends `ac` into `printf()` but `printf()` isn't servicing the child right now so as the child completes and parent's the `c` is printed. `printf()`, now done with the parent's printing tasks, turns to serving the child and prints the pending `ac`. So, you get `bcac`. Remember, `printf()` has 1 or more queues in front of it that may not be serviced in as-printed order unless each `printf()` is accompanied by an `fflush()`. `cout` includes a `fflush()`. – Wes Miller Dec 02 '13 at 21:04

1 Answers1

0

Don't always trust textbooks...

From the errata:

p. 772, Solution to Practice Problem 8.3. The sequence bcac is not possible. Strike the second to last sentence. The last sentence should be “There are three possible sequences: acbc, abcc, and bacc.” Please see Web Aside ECF:GRAPHS on the Web Aside page for an example of the process graph.

milktrey
  • 143
  • 1
  • 1
  • 7