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

Ruby readpartial on IO.pipe won't raise 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