如果IO.pipe的行为与资源类似,为什么需要在子进程中关闭管道?

时间:2013-05-05 09:23:50

标签: ruby ipc

以下代码有效,但如果读者和作者是父和子进程的共享资源,为什么它们首先关闭?

reader, writer = IO.pipe

fork do
  reader.close
  writer.puts "foobar"
end

writer.close
puts reader.read  

这对我来说没有意义,因为我认为应该在写操作之后关闭读写器,就像我制作的代码一样

reader, writer = IO.pipe                                                        

fork do                                                                         
    writer.puts "foobar"                                                  
    writer.close                                                                
end                                                                             
Process.wait                                                                    
puts reader.read                                                                
reader.close       

我不知道为什么它不起作用。谁能给我一个想法?

1 个答案:

答案 0 :(得分:3)

发生了什么,引自Stormier, JesseWorking with UNIX Processeshttp://workingwithunixprocesses.com,2012)p。 93:

  

...当读者调用IO#读取时,它将继续尝试读取数据,直到它看到EOF(也称为文件结束标记[2])。这告诉读者没有更多的数据可供阅读。

     

只要作者仍处于打开状态,读者可能会看到更多数据,因此等待。通过在读取之前关闭写入器,它会在管道上放置一个EOF,以便读取器在获取初始数据后停止读取。如果你跳过关闭作者,那么读者将阻止并继续尝试无限期阅读。

如果你要与IO(包括套接字)一起工作,我强烈建议给他的书读一读。

如您在其他问题How to maintain the TCP connection using Ruby?中所述,您可以手动强制缓冲区使用IO#flush进行刷新,或将缓冲区设置为在写入/读取后始终同步,方法是将IO#sync=设置为{ {1}}。