Linux-UNIX/Linux pipe() 子进程为何需要close(fd[1])

发布于 2016-10-13 16:41:39 字数 2456 浏览 1388 评论 1

在学习《UNIX网络编程第2卷第2版》的第4章的习题1时,有这样一个疑惑:
“In the transition from Figure 4.3 to Figure 4.4, what could happen if the child did not close(fd[1])?”
作者的解释如下:
"If fd[1] were left open in the child when the parent terminated, the child's read of fd[1] would not return an end-of-file, because this descriptor is still open in the child. By closing fd[1] in the child, this guarantees that as soon as the parent terminates, all its descriptors are closed, causing the child's read of fd[1]to return 0. "
Figure 4.3 to Figure 4.4

有没有一个方法验证作者所说呢?


问题部分解决:
“如果有指向管道写端的文件描述符没关闭(管道写端的引用计数大于0),而持有管道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。”
--进程间通信--pipe

上面引用的链接说的很清楚了,于是有如下的测试程序:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define MAXLINE 256

int main()
{
int fd[2];
pid_t pid;
char buff[MAXLINE];

if (pipe(fd) < 0)
{
fprintf(stderr, "open a pipe failed!n");
exit(-1);
}

if ((pid = fork()) < 0)
{
fprintf(stderr, "fork failed!n");
exit(-1);
}
else if (pid == 0)
{
// child
int n;
//close(fd[1]);

while ((n = read(fd[0], buff, MAXLINE-1)) > 0)
{
buff[n] = '';
printf("msg len: %d, msg: %s", n, buff);
}

close(fd[0]);
exit(0);
}
else
{
// parent

int n;
close(fd[0]);

while ((n = read(STDIN_FILENO, buff, MAXLINE-1)) > 0)
{
/*
if (buff[0] == 'q')
break;
*/

buff[n] = '';
printf("write %d bytes to childn", n);
write(fd[1], buff, n);
}

close(fd[1]);
printf("parent out of while loopn");

waitpid(pid, NULL, 0);

printf("parent exit!n");

exit(0);
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

归属感 2017-08-18 12:50:47

我个人理解这有个先后问题,如果父进程先结束,那么很自然的所有子进程都会自动终结。但反过来,子进程先结束,父进程没有调用wait这个方法时,那么该子进程就会变成僵尸进程。至于僵尸进程的概念以及危害,google一下就明白了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文