При попытке дублировать эту проблему я увидел другую схему:
puts "start"
trap("INT") { puts "interrupted" }
sleep 5
puts "end"
В Ubuntu (Ruby 1.8.6) это выдает
start
interrupted
interrupted
(etc)
interrupted
end
Таким образом, «прерванные» отпечатки каждый раз, когда нажимается Crtl-C, до тех пор, пока не истечут 5 секунд. Под Windows (также Ruby 1.8.6) это выдает:
start
interrupted
end
т.е. он печатает «прервано» один раз и затем выходит.
Похоже, что при обработке SIGINT Ruby выходит из режима сна и переходит к следующему оператору. Мое предположение (махание рукой) заключается в том, что это связано с тем, что Ruby использует зеленые потоки вместо собственных потоков в Windows. Любые эксперты, пожалуйста, перезвоните здесь.
Вы можете эмулировать поведение Unix-y, перезапустив sleep
в обработчике:
puts "start"
trap("INT") do
puts "interrupted"
sleep 5
end
sleep 5
puts "end"
К сожалению, это сбрасывает таймер каждый раз, когда SIGINT перехватывается, поэтому он требует некоторого взлома:
$interval = 5
def go_to_sleep(secs)
$started = Time.now
sleep secs
end
trap("INT") do
puts "interrupted"
time_to_sleep = [0,$interval - (Time.now - $started)].max
if time_to_sleep > 0
sleep time_to_sleep
end
end
puts "one"
go_to_sleep($interval)
puts "two"
go_to_sleep($interval)
puts "three"
go_to_sleep($interval)