Ruby,windows,active_record和Control-C

什么是active_record做的窗口下的信号进程(我没有看到这与mac上相同的版本),导致它performance如此奇怪? 例如:

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,但是activerecord要求之后的第一个中断会导致脚本终止。 在上述情况下,陷阱仍然执行,它只是不允许程序继续。 通常。

删除第二个陷阱电话对行为没有任何影响。

真正的烦恼是,在某些情况下,陷阱根本没有执行。 考虑到这样做的整个目的是让我的代码自己清理(删除其在数据库中的足迹,所以下一个家伙看到一个理智的状态),这是一个真正的问题。 例如:

 require 'rubygems' require 'active_record' trap("INT"){puts "interrupted"} puts __LINE__ gets 

看到投注后按^ C将根本不执行陷阱。

我只看到这个问题后需要active_record。 有没有解决方法? 我很想知道这是一个错误,还是有某种解释。 正如我所说的,我没有任何问题在这个重复的CS结果陷阱过程的多次执行。

谢谢…

考虑到这样做的重点是让我的代码自己清理(删除其在数据库中的足迹…

你有没有考虑过使用数据库事务? 似乎这将是一个更容易的方法来解决这个问题。

当我试图复制这个问题时,我看到了一个不同的模式:

 puts "start" trap("INT") { puts "interrupted" } sleep 5 puts "end" 

在Ubuntu(红宝石1.8.6)这产生

 start interrupted interrupted (etc) interrupted end 

因此,每次按下Crtl-C时都会打印“中断”,直到5秒钟结束。 在Windows(也是Ruby 1.8.6)下,这会产生:

 start interrupted end 

即它打印一次“中断”,然后退出。

所以看起来,在处理SIGINT时,Ruby会退出睡眠例程并继续执行下一个语句。 我的猜测(手摇)是由于Ruby使用绿色线程而不是Windows上的本地线程。 任何专家请在这里钟声。

您可以通过在处理程序中重新启动sleep模拟Unix-y行为:

 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)