为什么命令退出后 shell 不等待命令的子进程?

为什么命令退出后 shell 不等待命令的子进程?

我一直在学习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()父进程来阻止,直到子进程被杀死

看:http://man7.org/linux/man-pages/man2/waitpid.2.html

答案2

shell 本身并不真正了解它启动的进程的子进程。比如说,shell 启动进程 A,然后启动进程 B,然后 A 退出。现在发生的情况是,B 继续运行,但成为initPID 1 的子级。它不会成为 shell 的子级。

_exit(2)手册页在 Linux 上(有POSIX 中类似的措辞):

该进程的任何子进程都由 继承init(1)。向该进程的父进程发送 SIGCHLD信号。

让祖父母继承无父进程并不是一个好主意,因为新的父进程需要负责接收SIGCHLD来自子进程的信号并调用wait()子进程。任何执行任何其他程序的程序都需要准备好处理任意数量的子进程。

当然,如果子进程持有 shell 仍在读取的管道(例如命令替换),则 shell 将不得不等待,因为只有在管道关闭后它才能知道它已收到所有输入。

相关内容