2012-08-23 72 views
1

一個實現方式是:困惑管道實現

#define STD_INPUT 0 
#define STD_OUTPUT 1 
pipeline(char *process1, char *process2) 
{ 
    int fd[2]; 

    pipe(&fd[0]); 
    if (fork() != 0) { 
     /* The parent process executes these statements. */ 
     close(fd[0]); 
     close(STD_OUTPUT); 
     dup(fd[1]); 
     close(fd[1]); /* this file descriptor not needed anymore */ 
     execl(process1, process1, 0); 
    } 
    else { 
     /* The child process executes these statements. */ 
     close(fd[1]); 
     close(STD_INPUT); 
     dup(fd[0]); 
     close(fd[0]); /* this file descriptor not needed anymore */ 
     execl(process2, process2, 0); 
    } 
} 

我利用這一個接着一個DUP電話,分別爲兩個語句的混淆。

close(fd[1]); /* this file descriptor not needed anymore */ 

close(fd[0]); /* this file descriptor not needed anymore */ 

我告訴描述不再是必要的,但對我來說這些描述符代表管道的兩端,那麼,爲什麼他們不再需要?

回答

4

pipe調用返回單向通信的讀描述符和寫描述符。但是,作者不需要讀取描述符(fd[0])。而且,讀者不需要寫描述符(fd[1])。因此,調用之後的每個進程關閉它不需要的描述符,並使用它需要的描述符。

所以,父母是你的例子中的作家。它首先關閉fd[0],然後關閉STD_OUTPUT。然後它複製fd[1],現在它將在STD_OUTPUT中,因爲它可用。由於管道的輸出描述符現在被複制,因此它不再需要,因此它被關閉。現在,當作者寫入STD_OUTPUT時,它將寫入管道的輸出描述符。

孩子,這是讀者,執行類似的邏輯,但在另一個描述符。它首先關閉fd[1],然後關閉STD_INPUT。然後它重複fd[0],這導致描述符位於STD_INPUT。複製後,管道的輸入描述符不再需要,因此它被關閉。現在,當讀者從STD_INPUT讀取某些內容時,它將從管道的輸入描述符中讀取數據。

+0

我的歉意,這個問題很模糊,我已經更新了。 我瞭解dup之前關閉的第一次使用,但不理解dup之後的第二次關閉。 – richard

+0

@richard:答案更新。 – jxh

+0

@richard:你不需要文件描述符的兩個副本,是嗎?一旦你複製它,你不需要原來的。 –