如何解决从父进程和子进程关闭管道
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
int main() {
int p[2];
pipe(p);
if (fork() == 0) {
// child
/*#0*/ close(p[1]);
int received = -1;
while (read(p[0],&received,4) != 0) {
printf("receive integer: %d\n",received);
received = -1;
}
printf("child exit\n");
exit(0);
} else {
// parent
/*#1*/ close(p[0]);
int sent = 42;
write(p[1],&sent,4);
/*#2*/ close(p[1]);
printf("wait for child\n");
wait(0);
}
printf("finished\n");
}
我试图理解 C 中的 fork
和 pipe
。这个程序派生了一个子进程,它从父进程接收一个整数,然后在管道关闭时退出。执行时打印
wait for child
receive integer: 42
child exit
finished
然而,在移除位置 close(p[1]);
的 #0
后,while 循环卡住了:read
将无限等待来自管道的传入变量,并且永远不会检测到管道已关闭。
有人可以向我解释为什么 p[1]
必须由父进程(位置 #2
)和子进程(位置 #0
)关闭?
解决方法
这是代码(来自 Linux 手册页),代码底部带有注释。 https://man7.org/linux/man-pages/man2/pipe.2.html
在 /#2/ close(pipefd[1]),评论指出“读者将看到 EOF”。这意味着没有任何东西可以再读入子进程,然后语句“read(p[0],&received,4)”将返回 0。在 Linux 手册页 https://man7.org/linux/man-pages/man2/read.2.html 声明“成功时,返回读取的字节数(零表示文件结束)”
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int
main(int argc,char *argv[])
{
int pipefd[2];
pid_t cpid;
char buf;
if (argc != 2) {
fprintf(stderr,"Usage: %s <string>\n",argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Child reads from pipe */
close(pipefd[1]); /* Close unused write end */
while (read(pipefd[0],&buf,1) > 0)
write(STDOUT_FILENO,1);
write(STDOUT_FILENO,"\n",1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
} else {/* Parent writes argv[1] to pipe */
close(pipefd[0]); /* Close unused read end */
write(pipefd[1],argv[1],strlen(argv[1]));
/*#2*/ close(pipefd[1]); /* Reader will see EOF */
wait(NULL); /* Wait for child */
exit(EXIT_SUCCESS);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。