如何解决从父进程读取子进程的写入
在下面的代码中,我分叉了 5 次以创建 5 个子进程,每个子进程接收
来自父进程的字符串,子进程将 child-i
写回父进程
其中 i
是子进程 for 循环中的循环计数器。当我运行这个程序时,我
只看到 child-0
然后程序挂起。
int main(int argc,char *argv[])
{
int num_processes = 5;
int pipefd[2 * num_processes][2];
pid_t cpid;
char buf;
if (argc != 2)
{
fprintf(stderr,"Usage: %s <string>\n",argv[0]);
exit(EXIT_FAILURE);
}
for (int i = 0; i < 2 * num_processes; i++)
{
if (pipe(pipefd[i]) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < num_processes; i++)
{
cpid = fork();
if (cpid == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0)
{ /* Child reads from pipe */
close(pipefd[i][1]); /* Close unused write end */
while (read(pipefd[i][0],&buf,1) > 0)
{
}
char buf[12];
snprintf(buf,12,"child-%d",i);
write(pipefd[num_processes + i][1],buf,strlen(buf));
write(STDOUT_FILENO,"\n",1);
close(pipefd[i][0]);
close(pipefd[num_processes + i][0]);
break;
}
else
{ /* Parent writes argv[1] to pipe */
/* Close unused read end */
write(pipefd[i][1],argv[1],strlen(argv[1]));
close(pipefd[i][1]); /* Reader will see EOF */
wait(NULL); /* Wait for child */
char buf;
while (read(pipefd[num_processes + i][0],1) > 0)
{
write(STDOUT_FILENO,1);
}
close(pipefd[num_processes + i][0]);
}
}
_exit(EXIT_SUCCESS);
}
解决方法
当我运行这个程序时
只看到 child-0
然后程序挂起。
是的,因为父节点无限期地等待从 pipefd[num_processes + i][0]
读取更多数据。考虑一下:
while (read(pipefd[num_processes + i][0],&buf,1) > 0)
从您的代码的其他部分来看,您似乎意识到在写端关闭之前,进程在从管道读取时不会看到 EOF,但也许您没有认识到所有句柄 在写端需要在底层打开的文件描述关闭之前关闭。或者您可能只是没有考虑到父进程在它创建的每个管道的每一端都有一个副本。只要 pipefd[num_processes + i][0]
打开,它永远不会在 pipefd[num_processes + i][1]
上看到 EOF,无论孩子做什么。
作为处理管道的最佳实践,涉及的每个流程都应在不再需要保持打开状态时立即关闭每个管道末端。尤其是写端,因为不关闭它们很容易让你陷入更深层次的麻烦,但让读端打开会导致资源泄漏,这也可能会咬你。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。