【问题标题】:Closing pipe file descriptor in C在C中关闭管道文件描述符
【发布时间】:2014-03-28 17:37:00
【问题描述】:

代码如下:

int main() {

    int fd[2];
    pipe(fd);
    int r = fork();
    if (r > 0) { //parent
        close(fd[0]);
        // do a bunch of things
    } else { //child
        close(fd[1]);
        // do a bunch of things
    return 0;
}

这是一段代码,父级写入管道,子级从管道读取。我的问题是:对于两个关闭语句,它们到底是什么关闭?父母和孩子应该共享同一个文件,即 fd[0] 和 fd[1]。如果 fd[0] 在 parent 中关闭,它不应该在 child 中也关闭吗?

【问题讨论】:

  • 每个fd 都是管道的一端。

标签: c pipe


【解决方案1】:

http://linux.die.net/man/2/pipe pipe() 创建一个管道,该管道由两个文件描述符组成,这两个文件描述符对应于管道的两个“端”,即读取端和写入端。它与文件实际上不是一回事。内核正在从写端读取数据,为你缓冲,然后传输到读端。

这应该很明显为什么pipe() 创建了两个文件描述符。 writer 将所需的所有数据写入 write fd 并关闭 fd。这也会触发发送EOF。阅读器通常会继续阅读数据,直到遇到EOF 并关闭它的结尾。在这种情况下,有一段时间 write fd 关闭但数据仍缓冲在管道中,等待读取器读取。有一个单一的 fd 没有意义,因为您需要在编写器和读取器进程之间进行另一层协调,否则谁将执行关闭,何时关闭?

【讨论】:

  • 那么在fork之后,管道有4个末端?
  • @Xufeng 不,在fork之后,管道在父进程和子进程之间共享。由您决定父级使用写入端还是读取端,反之亦然。
  • 父母和孩子是否共用2端?如果是这样,为什么关闭一个进程中的一端不会影响另一个进程中的同一端?还是 close() 并没有真正关闭端,它只是关闭了进程与端之间的连接?
  • 两个进程都有不同的文件描述符表,所以当你在一个进程中关闭描述符时,它会从对应的文件描述符表中删除。
  • @Xufeng 详细说明王子所说的(谁是正确的),管道及其“末端”与进程分开存在。您可以对fopenfork 执行类似的操作:原则上,父进程和子进程可以读取和写入同一个文件,尽管这具有潜在的危险并且您永远不需要这样做。
【解决方案2】:

pipe() 调用总是返回一个整数数组,其中数组的第一个元素是要从管道读取的读取描述符,第二个元素是要写入管道的写入描述符。管道提供单向通信。如果您在父项和子项中关闭 fd[0],则您无法从管道中读取,反之,如果您在两个进程中关闭 fd[1],您将无法写入管道,因此我们关闭读取一个进程中的描述符,以便该进程只能写入,而另一个进程将关闭写入描述符,这将使该进程只能从管道读取。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    相关资源
    最近更新 更多