gpt4 book ai didi

c - 在C中实现多管道

转载 作者:行者123 更新时间:2023-11-30 15:16:27 25 4
gpt4 key购买 nike

任何人都可以告诉我为什么我的以下尝试实现多个管道的代码不正确吗?我正在实现父子关系,因此不允许有父子关系,即所有子项都应该并行运行。当我输入命令 ls |猫 | cat,输出了ls的内容,但是提示符仍然提示我输入,即使我输入另一个字符也不会停止。我这样做的方式不对吗?

    int i;
int pipefd[num_of_pipe][2];
pid_t child_pid[num_of_child];

for (i = 0; i < num_of_child; i++) {
pipe(pipefd[i]);
if ((child_pid[i] = fork()) == 0) {
if (i == 0) {
close(pipefd[i][0]);
dup2(pipefd[i][1], STDOUT_FILENO);
close(pipefd[i][1]);
/* execvp something; */
} else if (i == num_of_child - 1) {
close(pipefd[i - 1][1]);
dup2(pipefd[i - 1][0], STDIN_FILENO);
close(pipefd[i - 1][0]);
/* execvp something */
} else {
close(pipefd[i - 1][1]);
dup2(pipefd[i - 1][0],0);
close(pipefd[i - 1][0]);
close(pipefd[i][0]);
dup2(pipefd[i][1],1);
close(pipefd[i][1]);
/* execvp something */
}
}
}

int k;
for (k = 0; k < num_of_child; k++) {
waitpid(child_pid[k], NULL, WUNTRACED);
printf("the %dth child returns\n", k + 1);
}

int j;
for (j = 0; j < num_of_pipe; j++) {
close(pipefd[j][0]);
close(pipefd[j][1]);
}
}

最佳答案

问题是您的两个 cat 进程都在等待其标准输入上的更多数据,因为并非所有管道写入端的文件描述符副本都会关闭。出现这种情况是因为父进程构建并保留所有管道文件描述符的数组,并且仅在 fork 所有子进程后才关闭它们。因此,每个子进程都会继承父进程迄今为止创建的每个打开的文件描述符,而不仅仅是那些供自己使用的文件描述符。在管道写端的所有 FD 都关闭之前,读端不会检测到 EOF。

因此,特别是,第三个子进程具有用于第二个子进程读取的管道的写入端的打开文件描述符。它会在退出时关闭它,但它不会退出,因为第二个进程保持打开第三个进程的管道的写入端。如果管道更长,问题会更严重。

您应该通过让主进程在不再需要文件描述符时立即关闭它们来处理该问题,以便它们不会被继承。使用当前的代码结构,您可以在 fork 循环的底部执行此操作。

其次,如果您实际上依赖函数调用的返回值来确保它们不会失败,那么您应该始终检查函数调用的返回值是否有错误指示符。

关于c - 在C中实现多管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33081748/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com