Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C linux中的等待进程_C_Linux_Bash_Shell - Fatal编程技术网

C linux中的等待进程

C linux中的等待进程,c,linux,bash,shell,C,Linux,Bash,Shell,我正在实现一个模拟Linux shell的程序,我有一个关于pipe实现的问题(命令中只有一个pipe的实现——在示例ls | grep中)—— 管道命令中的主进程A分叉并在其上创建进程B和waitpid。进程B再次分叉并创建进程C,然后B和C都使用execvp来转换为所需的命令。但是在这个实现中,没有人等待C,它应该创建一个僵尸进程。但奇怪的是,在我的程序中,我没有看到任何僵尸。 我需要一些帮助来理解原因——因为我还需要概括实现以支持命令中的任意数量的管道,这意味着如果我继续当前的实现,我将有

我正在实现一个模拟Linux shell的程序,我有一个关于pipe实现的问题(命令中只有一个pipe的实现——在示例ls | grep中)——

管道命令中的主进程A分叉并在其上创建进程B和waitpid。进程B再次分叉并创建进程C,然后B和C都使用execvp来转换为所需的命令。但是在这个实现中,没有人等待C,它应该创建一个僵尸进程。但奇怪的是,在我的程序中,我没有看到任何僵尸。
我需要一些帮助来理解原因——因为我还需要概括实现以支持命令中的任意数量的管道,这意味着如果我继续当前的实现,我将有许多没有人等待的进程——所以我需要理解它是否正确,如果不正确(很可能)如何修复它,以便我不仅可以在B上等待,还可以在C上等待等等。

您的程序中将不会有任何zoombie进程。 Zoombie是在父进程等待已终止的进程时创建的。 在您的程序中,一旦B退出,进程C将被init进程采用

注意:如果进程B甚至在C退出之前就退出,那么您可能无法读取/写入C运行的命令的状态,这可能会产生很多问题


解决方案:使用vfork而不是fork。vfork确保父进程和子进程将按顺序运行,因此不会出现歧义。

一旦进程B死亡,C将被
init
采用,然后
init
等待()
在其上,因此C将在它和B终止后几乎立即消失
init
对所有孤儿都这样做,正是为了防止僵尸进程永远悬在那里


因此,您只能在父进程仍处于活动状态时看到僵尸进程。这是有意义的,因为将进程保持在僵化状态的唯一一点是要有一个包含终止状态等的地方,这样父进程就可以在准备就绪时抓住它们。如果父进程已经退出,那么显然它不关心剩余的信息,因此系统可以(并且将)安全地删除该信息以及包含该信息的僵尸进程。

我没有投反对票,但可能也是因为错误。“等待一个已经死亡的进程”是如何摆脱僵尸进程,而不是如何创建它们。如果进程B在C之前退出,那么不获取C的状态将不会“产生很多问题”,因为B显然不需要该状态,或者它不会退出。在最好的情况下,
vWork()
是一个糟糕的建议,但由于B和C都会立即执行
exec()
,所以说它们将“按顺序运行”是完全错误的.Two-question@paul:1)OP正在给管道加上顶点以运行某些命令,显然家长很有可能从管道的一端读/写。您的语句“B显然不需要该状态,否则它不会退出”。想象一下孩子正在等待响应(读/写)的情况来自父级,但已退出。POPEN系统调用中发生了类似的争用情况,在某些库中使用vWork解决了该问题。您刚才说了什么?“vfork无法确保它们正常运行?@PaulGriffiths:请你解释一下vfork。我引用了vfork手册页上的一句话。它说“vWork()与fork(2)的不同之处在于调用线程被挂起,直到子线程终止(正常情况下,通过调用_exit(2),或者异常情况下,在传递致命信号后),或者它调用execve(2)”。现在出现的重要问题是..您有自己版本的vWork()吗哪一个不能确保父母和孩子正常运行?或者是你黑客攻击了它。我很震惊。@SACHINGOYAL:你读了你刚刚发布的内容吗
vWork()
将确保C首先运行,直到它
exec()
s,在本例中,这基本上是立即运行的。在此之后,内核将按照正常方式调度这两个进程,而您处于正常情况下,无法保证哪个进程将在何时运行,或者哪个进程将首先完成。这正是
vWork()
(顺便说一句,它已从单一UNIX规范中删除)的设计目的,以避免为进程复制地址空间,而该进程在调用
exec()
后会立即替换地址空间。@SACHINGOYAL:这个问题中没有关于“同步父级和子级”的内容。你所说的没有一个是相关的。哇“所以你只能在父进程还活着的时候看到僵尸进程”。