问题描述
我试图了解Ruby中的IO.pipe如何工作,在下面的示例中,我将数据发送到io管道,并在完成数据发送后关闭流。在子进程中,我使用readpartial方法读取数据。根据文档,在关闭流时,readpartial应该引发EOFError,但是我最终遇到了被阻塞的进程,我理解的对吗?
# ruby 2.6.3
r,w = IO.pipe
pid = fork do
loop do
puts r.readpartial(1024)
sleep 0.1
rescue EOFError
puts "End of File"
break
end
end
1000.times do |t|
w.write "xyz #{t}"
end
w.close
Process.wait(pid)
解决方法
您需要在子级和父级中关闭管道的写端。
在分叉之后,您实际上对管道有两个写端和两个读端。在父级中关闭写端时,子级中的写端仍处于打开状态,因此对readpartial
的调用将被阻止。
您只需在分叉孩子后立即致电w.close
:
pid = fork do
w.close
loop do
#...
通常,您也可以在分叉后立即在父级中关闭读取端(尽管在这种情况下并不重要):
pid = fork do
#...
end
r.close