2016-02-25 55 views
0

我试图理解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])文件描述信息在儿童和父母的过程中。第二,在父母中使用write,父母使用read,但是在小孩到达write之前如果父母的处理到达read,并且试图从没有任何东西的管子读取?谢谢!

+4

关闭:因为最好关闭你不需要的东西。对于第二个问题:这些是潜在的阻塞功能。因此,从空管读取将阻止读者进程,直到有东西写入管道。 –

+0

缩进时,请勿使用制表符。因为每个文字处理器/编辑器都有不同的制表位/制表符宽度设置。建议每个缩进级别使用4个空格,因为即使使用可变宽度的字体,该空间也足够宽。 – user3629249

回答

1

丹尼尔怨妇给你99%的答案已经在一个非常简洁和易于理解的方式:

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

我会尽量详细说明。

关闭

当一个进程被分叉,它打开的文件被复制。

每个进程对允许打开多少个文件描述符有限制。如文档中所述:管道的每一侧都是一个单独的fd,这意味着管道需要两个文件描述符,在您的示例中,每个进程只使用一个

通过关闭不使用的文件描述符,可以释放资源有限,并且可能需要进一步研究。

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

此外,尽管在退出时释放资源是“可选的”,但这是一种很好的做法。没有正确发布的资源应该由操作系统来处理...

...但是操作系统也是我们程序员编写的,我们确实犯了错误。所以只有声明资源并知道资源的人才会释放资源才有意义。

竞态条件readwrite前):

POSIX定义了一些行为使readwrite和管道的好选择为线程和进程的并发同步。您可以在the Rational section for write上阅读更多关于它的信息,但这里有一个快速简要介绍:

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

此外,IO操作atomic,这意味着:

  • 你将永远不会被读取,并在同一时间写作。一个read操作将等到从管道读取(反之亦然)

  • 如果两个线程在同一时间打电话read,每次都会得到一个串行(不平行)响应,阅读前write操作完成从管道(或插座)顺序 - 这使得管道的并行处理的好工具。

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

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

您的应用程序将等待永远一些数据可用,为read操作完成(这将再次80( sizeof(readbuffer))字节被读取,或者如果在读取期间EOF状态改变)。