2012-11-02 44 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