gpt4 book ai didi

c - 管道:关闭管道数组中的文件描述符

转载 作者:太空宇宙 更新时间:2023-11-04 11:53:38 25 4
gpt4 key购买 nike

我正在为我的系统编程类(class)学习 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);
}
}
}

我将列出我现在理解的内容:

  1. 我理解父进程和子进程需要关闭那些他们不需要使用的 fds,在这种情况下,子进程正在写给父进程,所以父进程需要关闭写端口,子进程需要关闭读端口。
  2. 我了解文件描述符在父进程和子进程之间共享。

上面的代码是我的lecture slide给出的,具体有一点让我感到困惑。

在循环中,我观察到每个 child 在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);
}

目前我的理解是,每个 child 在被 fork 分娩后都会关闭自己的阅读端口,我认为后面创建的 child 不应该担心关闭前一个 child 的阅读端口。

但是看了这段代码我的理解好像不太对:

        // 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);
}
}

我不明白为什么后一个 child 要关闭前一个 child 的阅读端口,那些 child 创建后那些阅读端口不是已经关闭了吗?

谢谢你帮助我。 :)

最佳答案

一个描述符在所有打开它的进程都关闭它之前并没有真正关闭。由于每个子进程都继承了前一个进程的所有管道描述符,因此他们应该关闭所有未使用的管道描述符。

关闭读取端口的主要原因是,如果写入进程在读取器退出后尝试写入管道,则会收到错误或信号。如果其他 child 保持所有阅读端口打开,则在所有后续 child 退出之前不会发生这种情况。

关于c - 管道:关闭管道数组中的文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55208428/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com