Pipe
管道的一端是否同時具有讀寫 fd?
據我了解,管道的一端同時具有讀寫 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 管道不是雙向的,它們只使用管道並關閉另一端(在將文件描述符複製到標準輸入或標準輸出之後,它實際上也關閉了另一端)。