理解pipe()函数

时间:2016-02-25 00:34:24

标签: c linux pipe fork

我正在尝试了解pipe()函数的工作原理,我有以下程序示例

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

我的第一个问题是,在子进程和父进程中使用close(fd[0])close(fd[1])关闭文件描述符可以获得什么好处。其次,我们在child中使用write,在父级中使用read,但是如果父进程在子进入read之前到达write并尝试从没有任何内容的管道中读取,该怎么办? ?谢谢!

1 个答案:

答案 0 :(得分:1)

Daniel Jour已经以非常简洁易懂的方式给出了99%的答案:

  

结束:因为关闭你不需要的东西是一种很好的做法。对于第二个问题:这些是潜在的阻塞功能。因此,从空管中读取将阻止读取器进程,直到将某些内容写入管道。

我会尝试详细说明。

<强>合

分叉进程时,其打开的文件会重复。

每个进程都限制了允许打开的文件描述符的数量。如文档中所述:管道的每一侧都是一个fd,这意味着管道需要两个文件描述符,在您的示例中,每个流程仅使用一个

通过关闭您不会使用的文件描述符,您可以释放供应有限且未来可能需要的资源。

例如,如果您正在编写服务器,那么额外的fd意味着您可以再处理一个客户端。

此外,虽然在退出时释放资源是&#34;可选&#34;,但这是一种很好的做法。未正确发布的资源应由操作系统处理......

...但操作系统也是由程序员编写的,我们确实犯了错误。所以只有声称拥有资源并了解它的人才能释放资源才有意义。

竞争条件read之前write):

POSIX定义了一些使readwrite和管道成为线程和进程并发同步的良好选择的行为。您可以在the Rational section for write上详细了解相关信息,但这是一个快速的概述:

默认情况下,管道(和套接字)是在所谓的&#34;阻塞模式&#34;中创建的。 这意味着应用程序将挂起,直到执行IO操作。

此外,IO操作是atomic,意思是:

  • 你永远不会同时阅读和写作。 read操作将等到write操作完成后再从管道读取(反之亦然)

  • 如果两个线程同时调用read,每个线程将获得串行(非并行)响应,从管道(或套接字)顺序读取 - 这使得管道很好的并发处理工具。

换句话说,当您的应用程序调用时:

 read(fd[0], readbuffer, sizeof(readbuffer));

您的应用程序将等待永久以使某些数据可用并完成read操作(将读取80(sizeof(readbuffer))个字节,或者如果在阅读期间EOF状态发生了变化。