什么时候和为什么我要关闭管道?

时间:2016-11-14 07:48:18

标签: c pipe

我只是想了解管道,我正在研究一个例子:

#define _XOPEN_SOURCE 700

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

int main()
{
    pid_t p;
    int status;
    int pipefd[2];
    pipe(pipefd);
    p = fork();

    if(p == 0)
    {
        dup2(pipefd[1], 1);
        close(pipefd[0]);
        close(pipefd[1]);

        execlp(argv[1], argv[1], NULL); 
        perror(argv[1]);

        exit(1);
    }

    dup2(pipefd[0], 0);
    close(pipefd[0]);
    close(pipefd[1]);

    execvp(argv[2], argv+2);
    perror(argv[2]);

    return 1;
}

我不明白为什么这段代码在使用之前关闭了pipefd。

为什么要在这里关闭?

2 个答案:

答案 0 :(得分:5)

dup2(pipefd[1], 1);
close(pipefd[0]);
close(pipefd[1]);

这会将管道写入端的文件描述符复制到文件描述符#1(对应于stdout),程序正常输出将到达该文件描述符#1。然后它关闭管道两端的原始文件描述符,但是:

  • 管道本身的写入端不会被关闭,因为另一个打开的文件描述符(1)现在引用它
  • 进程已分叉,并且子进程在关闭自己的管道文件描述符之前类似地复制了管道的读取端。这意味着管道的读取端也在子进程中保持打开状态。

我们来关闭管道的原始管道文件描述符。但是,通常最好关闭我们不需要的文件描述符,这就是该程序的功能。多个文件描述符可以引用相同的管道(或文件或其他实体),并且管道/文件/其自身不会关闭,直到 all 引用它的文件描述符关闭。

答案 1 :(得分:1)

您已经使用dup2调用复制了描述符,因此子进程中不再需要pipefd[1]描述符。同样在父进程中。

实际上,描述符是一种有限的资源,如果你保持管道描述符是开放的,那么这个过程有两个较少的可用描述符。