2012-11-02 46 views
3

我需要立即捕捉线程中的异常并停止所有线程,所以我在我的脚本中使用abort_on_exception。不幸的是,这意味着异常不会引发到父线程 - 也许这是因为异常最终发生在全局范围内?红宝石不能救援或看到中止Thread.abort_on_exception

不管怎么说,这里的展示问题的示例:

Thread.abort_on_exception = true 

begin 
    t = Thread.new { 
    puts "Start thread" 
    raise saveMe 
    puts "Never here.." 
    } 
    t.join 
rescue => e 
    puts "RESCUE: #{e}" 
ensure 
    puts "ENSURE" 
end 

我该如何拯救使用abort_on_exception时在线程引发该异常?

下面是一个新的例子,显示更令人惊讶的事情。该线程能够在开始块内终止执行,但它不会引发任何异常?

Thread.abort_on_exception = true 
begin 
    t = Thread.new { raise saveMe }      
    sleep 1 
    puts "This doesn't execute" 
rescue => e 
    puts "This also doesn't execute" 
ensure 
    puts "But this does??" 
end 
+0

这是不是由于它所指的范围为例外全球。您将需要父进程需要“照顾”子进程。检查线程文档。 – vgoff

+0

从[Pickaxe](http://www.rubycentral.com/pickaxe/tut_threads.html)(可能会有点过时,但应该引导您朝着正确的方向。) – vgoff

+0

vgoff:镐手册没有除了说出abort_on_exception的功能外,还有任何信息,我已经知道了。 我不知道你的意思是“保姆” - 你能详细说明一下吗?我已经阅读了线程文档,并且使用了相当多的线程,但是我不明白如何在这种情况下将错误提交到线程之外。 –

回答

3

啊 - 我想通了。

abort_on_exception发送,显然是中止。线程是无关紧要的,我们的救援将不会看到一个基本的中止或者:

begin 
    abort 
    puts "This doesn't execute" 
rescue => e 
    puts "This also doesn't execute" 
ensure 
    puts "But this does?? #{$!}" 
end 

的解决方案是使用一个“救援异常”,这也抓住了中止。

begin 
    abort 
    puts "This doesn't execute" 
rescue Exception => e 
    puts "Now we're executed!" 
end 
+0

我很失望,我没有注意到救援的例外情况。 :( – vgoff

+2

具体来说,你可以'拯救SystemExit',因为拯救比'Exception'更具体的异常通常是一个好主意。 – lukeasrodgers