我正在实现一个模拟Linux shell的程序,我有一个关于管道实现的问题(命令中只有一个管道的实现 - 例如ls | grep) -
管道命令中的主进程A分叉并在其上创建进程B和waitpid。进程B依次再次分叉并创建进程C - 然后B和C都使用execvp以转换为所需的命令。但是在这个实现中没有人等待C应该创建一个僵尸进程。但奇怪的是,在我的节目中我没有看到任何僵尸。 我需要一些帮助来理解为什么 - 因为我还需要概括实现以支持命令中的任意数量的管道,这意味着如果我继续当前的实现,我将有许多人无法等待的进程 - 所以我需要了解如果它是正确的,如果不是(最有可能)如何解决它所以我不能只等待B而是等待C等等。
答案 0 :(得分:1)
一旦进程B死亡,C将被init
采用,然后init
就会wait()
,因此在它和B终止后C几乎会立即消失。 init
为所有孤儿做了这件事,正是为了防止僵尸进程永远地在那里停留。
所以你只会在父母还活着的时候看到僵尸进程。这是有道理的,因为将进程保持在僵尸状态的唯一要点就是在某处包含终止状态等,所以父进程可以在它准备就绪时抓住它们。如果父级已经退出,那么显然它并不关心剩余的信息,因此系统可以(并且将会)安全地删除该信息以及包含它的僵尸进程。
答案 1 :(得分:-1)
您的计划中不会有任何动画过程。 当父母在等待已经死亡的过程时,就会创建Zoombie。 在程序中,一旦B退出,进程C将被init进程采用。
注意:如果在退出C之前进程B将退出,那么您可能无法读取/写入由C运行的命令的状态,这可能会产生很多问题。
解决方案:使用vfork而不是fork .Vfork确保父和子将按顺序运行,因此不会有歧义。