2016-11-14 25 views
1

我只是想了解的管道,和我工作的一个例子:何时以及为什么我必须关闭管道?

#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。

为什么它在这里被关闭?

回答

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

这复制了管道的写入结束到文件描述符#1,其对应于标准输出文件描述符 - 到其上的程序正常输出将去。然后,关闭原来的文件描述符管道的两端,但是:

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

不是我们的关闭管道的原始管道文件描述符。但是,关闭我们不需要的文件描述符通常是一种好的做法,这就是这个程序所做的。多个文件描述符可以引用相同的管道(或文件,或其他实体),并且管道/文件/本身没有关闭,直到全部引用它的文件描述符都关闭。

1

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

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

相关问题