以下代码有效,但如果读者和作者是父和子进程的共享资源,为什么它们首先关闭?
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
我不知道为什么它不起作用。谁能给我一个想法?
答案 0 :(得分:3)
发生了什么,引自Stormier, Jesse。 Working with UNIX Processes(http://workingwithunixprocesses.com,2012)p。 93:
...当读者调用IO#读取时,它将继续尝试读取数据,直到它看到EOF(也称为文件结束标记[2])。这告诉读者没有更多的数据可供阅读。
只要作者仍处于打开状态,读者可能会看到更多数据,因此等待。通过在读取之前关闭写入器,它会在管道上放置一个EOF,以便读取器在获取初始数据后停止读取。如果你跳过关闭作者,那么读者将阻止并继续尝试无限期阅读。
如果你要与IO(包括套接字)一起工作,我强烈建议给他的书读一读。
如您在其他问题How to maintain the TCP connection using Ruby?中所述,您可以手动强制缓冲区使用IO#flush
进行刷新,或将缓冲区设置为在写入/读取后始终同步,方法是将IO#sync=
设置为{ {1}}。