我有一个简单的测试用例,用于从通过 MRI 并在 JRuby 1.7+ 中失败的管道读取。它被报告为JRUBY-6986中的一个严重错误。
tl; dr为什么从管道中完美读取 16kb(16384 字节)文件而 16kb + 1 字节文件失败?在另一个系统上,发现阈值为 72kb(73728 字节)。
$ ruby testpipe.rb 16384 开始……没挂! $红宝石testpipe.rb 16385 开始...^C
在那里,脚本以 16kb + 1 字节的大小挂起。
require 'open3'
path = "test.txt"
File.open(path, 'w') { |f| f.write('Z' * ARGV[0].to_i) }
STDOUT.write "Starting..."
Open3.popen3('cat', path) do |stdin, stdout, stderr|
stdin.close
readers = [stdout, stderr]
while readers.any?
ready = IO.select(readers, [], readers)
# no writers
# ready[1].each { ... }
ready[0].each do |fd|
if fd.eof?
fd.close
readers.delete fd
else
# read from pipe one byte at a time
fd.readpartial 1
end
end
end
end
puts "didn't hang!"
某些操作系统或 JVM 缓冲区大小是否会导致发送不同的信号IO.select
或其他什么?
PS。我与Working With UNIX processes的作者Jesse Storimer进行了仔细检查,他认为我对等的使用是正确的。IO.select