我一直在学习UNIX进程,但无法理解一点。假设我们有这样的代码,
void fork_child()
{
if (fork() == 0) {
/* Child */
printf("Running Child, PID = %d\n",
getpid());
while (1)
; /* Infinite loop */
} else {
/* Parent */
printf("Terminating Parent, PID = %d\n",
getpid());
exit(0);
}
}
我知道我们显式地终止子进程,因为父进程之前就死掉了,但是当我运行代码时,shell 不会等待子进程中的 while 循环,它更像是在后台运行。这个问题的主要原因是什么?
谢谢
答案1
你需要调用wait()
父进程来阻止,直到子进程被杀死
答案2
shell 本身并不真正了解它启动的进程的子进程。比如说,shell 启动进程 A,然后启动进程 B,然后 A 退出。现在发生的情况是,B 继续运行,但成为init
PID 1 的子级。它不会成为 shell 的子级。
_exit(2)
手册页在 Linux 上(有POSIX 中类似的措辞):
该进程的任何子进程都由 继承
init(1)
。向该进程的父进程发送SIGCHLD
信号。
让祖父母继承无父进程并不是一个好主意,因为新的父进程需要负责接收SIGCHLD
来自子进程的信号并调用wait()
子进程。任何执行任何其他程序的程序都需要准备好处理任意数量的子进程。
当然,如果子进程持有 shell 仍在读取的管道(例如命令替换),则 shell 将不得不等待,因为只有在管道关闭后它才能知道它已收到所有输入。