CSAPP全球版练习题8.3是否存在勘误?输出序列是否完整?
CSAPP练习题8.3输出序列疑问解析
CSAPP全球版受众较少,无法确认第8章《异常控制流》第781页的练习题8.3是否完全正确,仅找到其他版本的相关勘误且未被采纳。
题目代码
int main() { if (Fork() == 0) { printf("9"); fflush(stdout); } else { printf("0"); fflush(stdout); waitpid(-1, NULL, 0); } printf("3"); fflush(stdout); printf("6"); exit(0); }
其中Fork()是封装的系统调用,实现代码如下:
pid_t Fork(void) { pid_t pid; if ((pid = fork()) < 0) unix_error("Fork error"); return pid; }
疑问点
原答案给出的可能输出序列为936036、903636、093636,但存在疑问:930636是否也是有效序列?原答案是否遗漏了该序列?
分析结论
930636并非有效输出序列,原答案没有遗漏,原因如下:
- 父进程在
else分支中输出0后,会调用waitpid(-1, NULL, 0),这是阻塞式调用——父进程会暂停执行,直到任意子进程终止才会继续往下走。 - 子进程的执行流程是:输出
9→ 输出3→ 输出6→ 调用exit(0)终止。只有当子进程完成全部输出并终止后,父进程才会从waitpid的阻塞状态中恢复,继续输出3和6。 - 因此
0不可能出现在子进程的3之后、6之前——父进程输出0后就进入阻塞,必须等子进程输出6并终止才能继续,不存在子进程输出93后父进程就能输出0的情况。
内容的提问来源于stack exchange,提问作者RobSim
相关产品推荐
相关产品推荐

