c - 用一个循环和一个管道在 C 中实现无限管道
问题描述
我正在尝试构建一个 minishell,除了管道之外,我几乎什么都没有。我在这个网站和许多其他网站上阅读了很多答案,但我无法找到我的特定问题。
该序列应该在最右边的进程结束时结束,即:sleep 3 | sleep 3 | sleep 0
应该立即结束,而不是等待任何 sleep 3 进程。
*argvv 是指向第一个进程的指针(*argvv 是sleep 3
,*(argvv + 1) 是下一个sleep 3
,等等。我不知道发生了什么,但是文件描述符有问题,测试后一切都中断了。
例如,当输入为 时sh> ls | wc | wc
,输出为
sh> ls | wc | wc
sh> 1 3 25
,然后它等待一些输入。直到我再次按下回车它才完成。之后,sleep 3
不再工作。
欢迎任何帮助,非常感谢!
编辑:
好的,我编辑了代码,一切似乎都正常,除了 sleep 3 | sleep 0 持续 3 秒,而不是立即结束。我不知道如何解决这个问题。
void execute(char ***argvv)
{
pid_t pid;
int pd[2];
int in = 0;
while (*argvv != NULL) {
pipe(pd);
if ((pid = fork()) < 0)
{
perror();
exit(1);
}
else if (pid == 0) {
dup2(in, 0);
if (*(argvv + 1) != NULL)
dup2(pf[1], 1);
close(pd[0]);
close(pd[1]);
execvp((*argvv)[0], *argvv);
perror();
exit(1);
}
else
{
close(pd[1]);
in = pd[0];
if (*(argvv + 1) == NULL)
close(pd[0]);
argvv++;
}
wait(&pid);
}
}
解决方案
我认为部分问题可能在于使用wait()
. 它的 pid 参数是一个 OUTPUT,报告哪个fork()
ed 进程结束了。每个分叉的处理都结束了,需要对其进行wait()
编辑。当您运行第二个管道时,除了前面的一个管道之外的所有其他管道仍然准备好进行wait()
编辑。
通常,您有几种选择:
wait()
循环,直到您要结束的过程结束。wait()
循环,直到所有子流程结束。- 用于
waitpid()
查找特定的进程结束。 - 安排只有链中的最后一个进程是您的进程的子进程,使其余进程成为该进程的子进程。(这是由某个 shell 完成的,虽然我不记得是哪个。)这样做的问题是它为链中的最后一个进程留下了额外的子进程,这可能会使它感到困惑。
- 跟踪所有子进程,以及哪些已经结束。在后台运行管道时,这允许您显示管道的哪些部分仍在运行。(tcsh 做到这一点。bash 做到了一半。)
fork()
较早的管道成员两次,execvp()
在孙子中,然后exit()
在孩子中,并让孩子的父母wait()
在继续之前完成。这将孙子与父级断开连接,因此永远不需要等待。- 做涉及忽略的事情
SIGCHLD
,但这可能会给你带来很多悲伤,因为它要么全有,要么全无。
推荐阅读
- python - 如何检查数据帧字符串字段的python字节?
- flutter - 颤动中的动态下拉菜单,带有静态“添加新”按钮类型,如图所示
- java - 当多个类继承单个抽象类时使用构建器模式
- c++ - 如何将参数传递给从 C++ 调用的蓝图函数?
- python - 将 numpy 数组保存在 .txt 文件中
- tensorflow - 如何使 Tensorflow vid2depth 推理工作?
- c - 将光标移动到ncurses窗口中一行文本的末尾?
- android-studio - 防止 Android Studio 将 jcenter 添加到 build.gradle
- memory - hyperbus内存结构如何?
- ios - 后台提取停止在 ios 13 及更高版本上工作