为什么在读取和写入管道时需要关闭fds?

时间:2009-06-10 14:42:19

标签: c++ c multithreading pipe unix

这是一个example来说明我的意思:

#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);

}

但是,如果我的一个进程需要连续写入管道而另一个管道需要读取呢?

上面的示例似乎只适用于一次写入和一次读取。

5 个答案:

答案 0 :(得分:24)

您的管道是单向流 - 每端都有一个文件描述符。没有必要关闭()管道的任何一端以允许数据沿其传递。

如果您的管道跨越进程(即在fork()之前创建,然后父级和子级使用它进行通信)您可以有一个写入和一个读取结束。然后,最好关闭管道的不需要的末端。这将

  • 确保当写入端关闭管道时,读取端会看到它。举个例子,假设孩子是写作方,它就会死掉。如果父写入方未被关闭,则父级将不会从管道获得“eof”(零长度read()) - 因为管道具有打开的写入端。
  • 明确说明哪个进程正在进行写入以及哪个进程正在对管道进行读取。

如果您的管道跨越线程(在同一过程中),则不要关闭管道的不需要的末端。这是因为文件描述符由进程保存,并且为一个线程关闭它将为所有线程关闭它,因此管道将变得不可用。

没有什么可以阻止你让一个进程连续写入管道而另一个进程读取。如果这是一个问题,那么您可以提供更多详细信息来帮助您。

答案 1 :(得分:11)

执行fork后,所有fds都重复。每个过程都打开管道的两端。如果您只想使用一端,则应关闭另一端(如果您的进程写入,请关闭读取端)。

除了明显的事实,如果你不关闭描述符,操作系统将在打开的文件表中保留额外的条目,如果你不关闭管道的写端,读者将永远不会收到EOF,因为仍有将数据输入管道的方法。 AFAIK(和IIRC)没有关闭其他进程中的读取fd没有问题 - 也就是说,除了文件无缘无故地打开之外。

在退出应用程序之前关闭所有描述符(也就是说,在每个进程中完成读/写操作后关闭管道的另一端)也建议(这是好的做法,而不是它影响太大) )

答案 2 :(得分:0)

管道不会给你双向通道,它也不会是多播。一个管道只有两端,它没有一个写端和多个读端。

如果你想要很多读者,那么你需要尽可能多的管道来读取你的读者。

答案 3 :(得分:0)

“上面的示例似乎仅适用于一次写入和一次读取。”

这是因为在读取和写入代码后退出。您需要继续写入循环并循环读取以实现连续性。它似乎与FD关闭没有任何关系。正如之前的回复中所提到的,每个进程都需要一端,所以另一端关闭。

我希望我理解正确的查询。

答案 4 :(得分:0)

仅用于同步,以确保操作的原子性

相关问题