2

In studying CSAPP, I encounter the practice: list all of the possible output sequences for the following program:

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

the answer is :acbc abcc bcac bacc;

Why is bcac correct? The function waitpid() suspends execution of the calling process until the child process in its wait set terminates. So the parent can't not print c, until the child process terminate, which means the child prints both a and c.
I'm really confused about it. I don't know why bcac is correct. The parent process should hold or suspend until child terminates.

e0k
  • 6,961
  • 2
  • 23
  • 30
S.Tian
  • 29
  • 2
  • 5
    are you sure its `Fork()`? – Sourav Ghosh Mar 15 '16 at 11:30
  • 2
    Might be due to buffering. Output to `stdout` (which is what `printf` is using) is *line buffered* by default. Output isn't flushed until the buffer is full (will not happen here), there is a newline printed (does not happen here), there's an explicit `fflush` call (does not happen here), or the process exits and the out is flushed. – Some programmer dude Mar 15 '16 at 11:33
  • Probably another duplicate to: http://stackoverflow.com/q/2530663/694576 – alk Mar 15 '16 at 11:52
  • Fork() : pid_t Fork(void) { pit_t pid; if((pid = fork()) < 0) unix_error("Fork error"); return pid; } – S.Tian Mar 15 '16 at 11:53
  • 2
    The C library provides `pid_t fork(void)`. Please note the case. – alk Mar 15 '16 at 11:54
  • @alk See: https://github.com/mofaph/csapp/blob/master/code/src/csapp.c – Ctx Mar 15 '16 at 12:06
  • I found the exercise you are refering to here: http://square.seoultech.ac.kr/~icom/newsysprog/textbook/ch8.pdf . This is obviously an error in the script. You are correct, `bcac` is not a valid outcome. – Ctx Mar 15 '16 at 12:16
  • I thought there was a possibility that some POSIX system would return EINTR. seeing the csapp.c, it is not a possibility any more and I too say that `bcac` is not valid – Antti Haapala -- Слава Україні Mar 15 '16 at 12:27
  • You should define Fork in your code example, not in a comment. – Kaz Mar 15 '16 at 14:31

1 Answers1

1

As Joachim Pileborg suggests, this is a flushing output problem. Just use the following:

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

'\n' characters should automatically flush stdout or stderr. You can also use fflush(stdout);

jdarthenay
  • 3,062
  • 1
  • 15
  • 20
  • 1
    I tend to disagree, this can not be a buffering issue since exit() will flush stdout implicitly. – Ctx Mar 15 '16 at 12:18
  • @Ctx Is that completely sure the parent is awaken only after stdout is flushed? – jdarthenay Mar 15 '16 at 12:54
  • Yes, it is, with standard buffering you will _always_ get `acbc` with the OP's code. Assuming no buffering, additionally `abcc` and `bacc` are possible. `bcac` never is. – Ctx Mar 15 '16 at 13:53