C Minishell - 需要为管道实现杀死僵尸

Posted

技术标签:

【中文标题】C Minishell - 需要为管道实现杀死僵尸【英文标题】:C Minishell - Need to Kill Zombies for Pipeline Implementation 【发布时间】:2012-12-01 04:26:37 【问题描述】:

所以我正在 C 中构建一个 minishell(用于 unix)。我只是想出了如何让管道工作,但是我遇到了僵尸问题。假设我有:

echo a | echo b | echo c

当它应该输出“c”时,它不会输出任何东西。但是,如果我告诉我的 shell 执行每个子命令,然后在继续执行下一个命令之前等待,它就可以正常工作。但是,这不是一个真正的解决方案,因为我希望您在不等待的情况下获得管道之间的自然协调。

一旦执行最后一个命令,我很难设计一种有效的方法来等待所有僵尸。我在最后一次执行之后尝试这样做,但在 shell 退出之前:

while(waitpid(-1, NULL, WNOHANG) > 0);

但是,没有运气。到目前为止,唯一可行的方法是告诉我的 shell 执行每个子命令,然后在开始下一个命令之前等待。这是整个主 shell 文件:

http://pastebin.com/YV96mFy7

处理输入的主函数(processline())从第 105 行开始。

感谢您的帮助,如果您需要更多帮助,请随时询问。

【问题讨论】:

你知道WNOHANG 应该做什么吗?是的。这是错误的。您应该(a)捕获 SIGCHLD 并在那里等待。或者 (b) 知道你有多少个孩子,在没有 WNOHANG 的情况下等那么久。 哦,我如何捕获 SIGCHLD?我是否只是在父级中创建一个处理程序,然后在它获得 SIGCHLD 时等待?如果是这样,WNOHANG 与它有什么关系?谢谢:) 一般来说,您不能等待进程 1 完成后再启动进程 2。您可能会在 C Minishell — Adding Pipelines 找到一些帮助。 这是我的帖子,哈哈,我只是在第二个账号上发的。我看到你添加了更多内容,我去看看。 【参考方案1】:

改一下

while(waitpid(-1, NULL, WNOHANG) > 0);

收件人:

while(wait(NULL) > 0);

/* which is equivalent to */
while(waitpid(-1, NULL, 0) > 0);

这将导致父进程等待所有子进程完成,如果您不想阻塞父进程,则捕获SIGCHLD 并在信号处理程序中调用wait()

【讨论】:

我认为你说的不是这个意思。您是否打算在第二个循环中使用普通的wait()waitpid() 需要三个参数,但我认为 waitpid(-1, 0, 0)wait(0) 相同。 @JonathanLeffler 是的,这正是我的意思,我复制了该行并忘记将其更改为 wait,谢谢。

以上是关于C Minishell - 需要为管道实现杀死僵尸的主要内容,如果未能解决你的问题,请参考以下文章

【zombie】如何查看并杀死僵尸进程?

监控并优雅地杀死或重用僵尸 GeckoDriver 实例

在Linux系统中查看进程及杀死僵尸进程的方法

如何杀死僵尸进程

如何使用子进程模块杀死(或避免)僵尸进程

Linux上寻找并杀死僵尸进程