2016-11-14 74 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]描述符在子進程中不再需要。同樣在父進程中。

事實上,描述符是一個有限的資源,如果你保持管道描述符打開,那麼這個過程有兩個可用的描述符。

相關問題