[英]Pipe: Closing file descriptors in an array of pipe
我现在正在学习Linux并为我的系统编程课程提供管道,我现在很难理解在管道数组中关闭文件描述符。
// write the code to loop over the command line arguments (remember to skip the executable name)
for (int i = 1; i < argc; i++) {
// call pipe before we fork
if ((pipe(pipe_fd[i-1])) == -1) {
perror("pipe");
exit(1);
}
// call fork
int result = fork();
if (result < 0) { // case: a system call error
// handle the error
perror("fork");
exit(1);
} else if (result == 0) { // case: a child process
// child does their work here
// child only writes to the pipe so close reading end
if (close(pipe_fd[i-1][0]) == -1) {
perror("close reading end from inside child");
exit(1);
}
// before we forked the parent had open the reading ends to
// all previously forked children -- so close those
int child_no;
for (child_no = 0; child_no < i-1; child_no++) {
if (close(pipe_fd[child_no][0]) == -1) {
perror("close reading ends of previously forked children");
exit(1);
}
}
int len = strlen(argv[i]);
// write len to the pipe as an integer
if (write(pipe_fd[i-1][1], &len, sizeof(int)) != sizeof(int)) {
perror("write from child to pipe");
exit(1);
}
// I'm done with the pipe so close it
if (close(pipe_fd[i-1][1]) == -1) {
perror("close pipe after writing");
exit(1);
}
// exit so I don't fork my own children on next loop iteration
exit(0);
} else {
// in the parent but before doing the next loop iteration
// close the end of the pipe that I don't want open
if (close(pipe_fd[i-1][1]) == -1) {
perror("close writing end of pipe in parent");
exit(1);
}
}
}
我将列出我现在所了解的内容:
上面的代码是从我的演讲幻灯片中给出的,我特别对一件事感到困惑。
在循环中,我观察到每个孩子在通过fork创建该孩子后都会关闭其读取端口,并且执行此操作的代码是:
else if (result == 0) { // case: a child process
// child does their work here
// child only writes to the pipe so close reading end
if (close(pipe_fd[i-1][0]) == -1) {
perror("close reading end from inside child");
exit(1);
}
据我所知,在这一点上,每个孩子在分娩后都会关闭自己的阅读口,我认为后者的孩子们不应该担心关闭以前孩子的阅读口。
但是在阅读以下代码后,我的理解似乎不正确:
// before we forked the parent had open the reading ends to
// all previously forked children -- so close those
int child_no;
for (child_no = 0; child_no < i-1; child_no++) {
if (close(pipe_fd[child_no][0]) == -1) {
perror("close reading ends of previously forked children");
exit(1);
}
}
我不明白为什么后一个孩子应该去关闭前一个孩子的阅读端口,一旦创建了这些孩子,这些阅读端口就已经关闭了吗?
谢谢你的协助。 :)
直到打开描述符的所有进程都将其关闭,描述符才真正关闭。 由于每个子进程都继承了前一进程中的所有管道描述符,因此它们应该关闭所有未使用的进程。
关闭读取端口的主要原因是,如果读取器退出后尝试写入管道,写入过程将收到错误或信号。 如果其他子项将所有读取端口保持打开状态,则直到所有后续子项都退出后,这种情况才会发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.