平行管道没有在C中关闭?
Posted
技术标签:
【中文标题】平行管道没有在C中关闭?【英文标题】:Parallel pipes not closing in C? 【发布时间】:2012-02-05 02:19:08 【问题描述】:我正在尝试在 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 我在父级 else 块中尝试了以下操作,但没有成功
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 的子进程
【问题讨论】:
您需要显示包含 pipe() 调用和 fork() 调用的代码。一旦与 cat 的标准输入关联的管道上的所有写入端文件描述符都关闭,cat 就会终止。您描述的这种问题几乎可以肯定是无法关闭文件描述符。可能 cat 本身的调用仍然打开它。 当你分叉时,父节点的管道两端都打开了。除非您在某个时候指定 p1 = fd[1],否则父级永远不会关闭 fd[1]。 Cat 将在父级关闭该文件描述符之前终止,因为 cat 正在等待更多数据。 【参考方案1】:最有可能的是,父母正在打开管道的另一侧。 ls 在 cat 的管道写入端有一个打开的文件描述符,但父级也是如此。 cat 在所有写入端文件描述符都关闭之前不会退出。可能,您只需要在调用 waitpid 之前反转代码并关闭管道即可。
【讨论】:
以上是关于平行管道没有在C中关闭?的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式在 C 中检查 NIC 在 linux 中关闭时是不是有链接