3

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

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       

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

4

1 回答 1

3

发生了什么,引自Stormier, Jesse使用 UNIX 进程( http://workingwithunixprocesses.com , 2012) p。93:

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

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

如果您要大量使用 IO(包括套接字),我强烈建议您阅读他的书。

正如您在其他问题中所述如何使用 Ruby 维护 TCP 连接?您可以手动强制缓冲区刷新使用IO#flush或将缓冲区设置为在写入/读取后始终同步,方法是设置IO#sync=true.

于 2013-05-05T14:56:17.460 回答