【发布时间】:2010-10-19 17:51:00
【问题描述】:
active_record 对 windows 下的信号处理做了什么(我在 mac 上没有看到相同的版本)导致它的行为如此奇怪?例如:
require 'rubygems'
trap("INT"){puts "interrupted"}
puts __LINE__
sleep 5
require 'active_record'
trap("INT"){puts "interrupted again"}
puts __LINE__
sleep 5
当我运行上面的代码(ruby 1.8.6、gem 1.3.1、activerecord 2.2.2)时,我可以在第一次睡眠期间按我喜欢的次数多次点击 ^C,但在 require 之后的第一次中断activerecord 导致脚本终止。在上述情况下,陷阱仍然执行,只是无法让程序继续执行。通常。
删除第二个陷阱调用不会对行为产生任何影响。
真正令人烦恼的是,在某些情况下,陷阱根本无法执行。考虑到这样做的全部目的是让我的代码自行清理(删除它在数据库中的足迹,以便下一个人看到一个理智的状态),这是一个真正的问题。例如:
require 'rubygems'
require 'active_record'
trap("INT"){puts "interrupted"}
puts __LINE__
gets
看到 puts 后按 ^C 根本不会执行陷阱。
我只在需要 active_record 后才看到这个问题。有解决方法吗?我很想知道这是一个错误还是有某种解释。正如我所说,我在 mac 上对此没有任何问题 - 重复 ^Cs 会导致陷阱过程的多次执行。
谢谢...
【问题讨论】:
-
嘿,这是 Windows 上的 Ruby。很高兴它不会让你的机器着火(我认为他们在 1.4 中修复了这个错误)。
-
只是好奇,但为什么有必要捕获任何 SIGINT,而不是在代码的某些部分中挽救 ruby 的中断异常?也许将您的解决方案缩小到只需要长时间运行的进程就足够了,而不是在代码中的任何地方捕获 any SIGINT 。
-
如果您想进一步测试陷阱的调用,您可以调用
Process.kill "INT", $$,如ntecs.de/old-hp/s-direktnet/ruby/uguide18.html。此外,trap 的返回值是它会执行的前一个 Proc,因此您可以检查活动记录是否正在改变它。在我的 Mac 上似乎没有。 -
您能否使用
Process.kill添加上述代码的一个版本,该版本在不让用户按Ctrl-C 的情况下执行显示问题? -
这是另一篇可能有帮助的文章,虽然我不确定为什么 TERM 会在 Windows 上执行:kseebaldt.blogspot.com/2009/02/it-trap.html
标签: ruby windows activerecord exception-handling interrupt