我正在尝试并行地在 C 中进行管道传输,但由于某种原因它没有关闭......它只是在等待......不确定我是否描述得很好因为我是新手,但这是代码
... some code up here
if(child_pid == 0) {
if(p0 >=0 && p1 == -1) {
dup2(p0, STDIN_FILENO);
close(p0);
close(p1);
}
else if (p0 == -1 && p1 >= 0) {
dup2(p1, STDOUT_FILENO);
close(p0);
close(p1);
}
else if (p0 >= 0 && p1 >=0) {
dup2(p0, STDIN_FILENO);
dup2(p1, STDOUT_FILENO);
close(p0);
close(p1);
}
if (input)
iofunc(input, 0);
if (output)
iofunc(output, 1);
if (sub){
command_exec (SUBSHELL_COMMAND, sub, -1, -1, -1);
exit(0);
}
else {
execvp(w[0], w);
exit(0);
}
}
else {
if (waitpid (-1, &child_status, 0) != child_pid)
child_status =-1;
close(p0);
close(p1);
return WEXITSTATUS(child_status);
}
... some code down here
当 p0 == -1 && p1 >= 0 时,进程退出/返回,但由于某种原因,当 p0 >= 0 && p1 == -1 时,进程只是挂起,管道不会关闭。我运行了一个命令 ls | cat 使用两个并行的子进程,其中 ls 写入 p1,而 cat 从 p0 读取。输出是正确的,但管道没有关闭并且 cat 从未退出。这是怎么回事?
@William 我在我的 parent else block 中尝试了以下内容,但它没有用
close(p0);
close(p1);
if (waitpid (-1, &child_status, 0) != child_pid)
child_status =-1;
@William这里是调用一个调用上面代码的函数的代码
int i = 0;
int num = 2;
int status;
pid_t pid;
pid_t pids[num];
int fd[2];
int p = pipe(fd);
int a;
int b;
//printf("pipe0:%d\n", fd[0]);
//printf("pipe1:%d\n", fd[1]);
for (i = 0; i < num; i++) {
if ((pids[i] = fork()) < 0) {
error(1,0, "child not forked");
} else if (pids[i] == 0) {
if (i == 0){
b = command_exec (c->type,
c->u.command[1],
0, f[0], p1);
}
else if (i == 1){
a = command_exec (c->type,
c->u.command[0],
1, p0, fd[1]);
}
exit(a && b);
}
}
while (num > 0) {
pid = wait(&status);
printf("Child with PID %ld exited with status 0x%x.\n", (long)pid, status);
num--;
}
printf 只打印完成 ls 而不是 cat 的子进程
最佳答案
很可能, parent 正在打开管道的另一侧。 ls 在管道的写入端有一个打开的文件描述符到 cat,但父进程也是如此。在所有写端文件描述符都关闭之前,cat 不会退出。可能,您只需要在调用 waitpid 之前而不是之后反转代码并关闭管道。
关于c - 平行管道没有在 C 中关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9146380/