簡體   English   中英

為什么在讀取和寫入管道時需要關閉fds?

[英]Why do I need to close fds when reading and writing to the pipe?

這是一個例子來說明我的意思:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!\n";
        char    readbuffer[80];

        pipe(fd);

        if((childpid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

                /* Send "string" through the output side of pipe */
                write(fd[1], string, (strlen(string)+1));
            exit(0);
    }
    else
    {
            /* Parent process closes up output side of pipe */
            close(fd[1]);

            /* Read in a string from the pipe */
            nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
            printf("Received string: %s", readbuffer);
    }

   return(0);

}

但是,如果我的一個進程需要連續寫入管道而另一個管道需要讀取呢?

上面的例子似乎只適用於一次寫入和一次讀取。

您的管道是單向流 - 每端都有一個文件描述符。 沒有必要關閉()管道的任何一端以允許數據沿其傳遞。

如果您的管道跨越進程 (即在fork()之前創建,然后父級和子級使用它進行通信),您可以有一個寫入和一個讀取結束。 然后,最好關閉管道的不需要的末端。 這將

  • 確保當寫入端關閉管道時,讀取端會看到它。 舉個例子,假設孩子是寫作方,它就會死掉。 如果父寫入端尚未關閉,則父級將不會從管道獲得“eof”(零長度read()) - 因為管道具有打開的寫入端。
  • 明確哪個進程正在寫入以及哪個進程正在對管道進行讀取。

如果您的管道跨越線程 (在同一過程中),則不要關閉管道的不需要的末端。 這是因為文件描述符由進程保存,並且為一個線程關閉它將為所有線程關閉它,因此管道將變得不可用。

沒有什么可以阻止你讓一個進程連續寫入管道和另一個進程讀取。 如果這是一個問題,那么你可以給我們更多的細節來幫助你。

執行fork后,所有fds都重復。 每個過程都打開管道的兩端。 如果您只想使用一端,則應關閉另一端(如果您的進程寫入,請關閉讀取端)。

除了明顯的事實,如果你不關閉描述符,操作系統將在打開的文件表中保留額外的條目,如果你不關閉管道的寫端,讀者將永遠不會收到EOF,因為還有一種方法可以進入數據進入管道。 AFAIK(和IIRC)沒有關閉其他進程中的讀取fd沒有問題 - 也就是說,除了文件無緣無故地打開之外。

在退出應用程序之前關閉所有描述符(也就是說,在每個進程中完成讀/寫操作后關閉管道的另一端),也建議(這是好的做法,而不是它影響太大)

僅用於同步,以確保操作的原子性

管道不會給你雙向通道,它也不會是多播。 管道只有兩端,它沒有一個寫端和多個讀端。

如果你想要很多讀者,那么你需要盡可能多的管道來讀取你的讀者。

“上面的例子似乎只適用於一次寫入和一次讀取。”

那是因為在一次讀寫之后你的代碼退出了。 您需要繼續寫入循環並循環讀取以實現連續性。 它似乎與FD關閉沒有任何關系。 如前面的回復中所述,每個進程都需要一端,因此另一端關閉。

我希望我理解正確的查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM