Pipe

管道的一端是否同時具有讀寫 fd?

  • January 10, 2022

據我了解,管道的一端同時具有讀寫 fd,而另一端也具有讀寫 fd。這就是為什麼當我們使用 寫入時fd[1],我們正在關閉fd[0]管道同一側的讀取端,例如,當我們使用從第二端讀取時,fd[0]我們關閉該fd[1]端的。我對麼?

是的,使用 pipe() 製作的管道有兩個文件描述符。fd[0]閱讀和fd[1]寫作。

不,您不必關閉管道的任何一端,它可以用於雙向通信。

編輯:在您想知道這與 ​​的評論中ls | less,我也會解釋一下:

您的 shell 具有三個打開的文件描述符:0 (stdin)、1 (stdout) 和 2 (stderr)。當一個 shell 執行一個命令時,它會做這樣的事情(我已經簡化了一點:

pid = fork();
if(pid == 0) {
   /* I am the child */
   execve(...); /* Whatever the user asked for */
}
else {
   waitpid(pid); /* Wait for child to complete */
}

文件描述符 0、1 和 2 由子級繼承,因此輸入/輸出按預期工作。如果你這樣做ls | less,重定向會發生一些稍微不同的事情:

int pipe[2];
pipe(pipe, 0);

pid1 = fork();
if(pid1 == 0) {
   /* This is ls, we need to remap stdout to the pipe. We don't care about reading from the pipe */
   close(pipe[0]);
   close(1);
   dup2(pipe[1], 1);
   execve(...);
}
else {
   pid2 = fork();
   if(pid2 == 0) {
       /* This is less, it reads from the pipe */
       close(pipe[1]);
       close(0);
       dup2(pipe[0], 0);
       execve(...);
   }
   else {
       waitpid(pid1);
       waitpid(pid2);
   }
}

因此,shell 創建了管道、分叉,並在執行之前將管道重新映射到子程序的標準輸入或標準輸出,使數據從程序 1 流向程序 2。由於 shell 管道不是雙向的,它們只使用管道並關閉另一端(在將文件描述符複製到標準輸入或標準輸出之後,它實際上也關閉了另一端)。

引用自:https://unix.stackexchange.com/questions/70534