コードで説明するのが最も簡単です。
require 'timeout'
puts "this block will properly kill the sleep after a second"
IO.popen("sleep 60") do |io|
begin
Timeout.timeout(1) do
while (line=io.gets) do
output += line
end
end
rescue Timeout::Error => ex
Process.kill 9, io.pid
puts "timed out: this block worked correctly"
end
end
puts "but this one blocks for >1 minute"
begin
pid = 0
Timeout.timeout(1) do
IO.popen("sleep 60") do |io|
pid = io.pid
while (line=io.gets) do
output += line
end
end
end
rescue Timeout::Error => ex
puts "timed out: the exception gets thrown, but much too late"
end
2 つのブロックの私のメンタル モデルは同じです。
それで、私は何が欠けていますか?
編集: drmaciver は、最初のケースでは何らかの理由でパイプ ソケットが非ブロック モードになることを Twitter で提案しましたが、2 番目のケースではそうではありません。これが発生する理由は考えられませんし、記述子のフラグを取得する方法もわかりませんが、少なくとももっともらしい答えですか? その可能性に取り組んでいます。