IO.pipe上的Ruby readpartial不会引发EOFError

问题描述

我试图了解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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...