【问题标题】:Ruby: rescue doesn't rescue from threadRuby:救援不会从线程中救援
【发布时间】:2014-11-11 00:27:26
【问题描述】:
Thread.abort_on_exception = true

begin
    #code in this block doesn't matter at all, it just needs to produce errors.
    [1, 2].each do |i|
        a = Thread.new do
            errory
        end
    end 
    a.join 
rescue Exception
    puts 'error!'
end

由于某种原因引发/home/lakesare/Desktop/multithreading/test.rb:6:in 'block (2 levels) in <main>': undefined local variable or method 'errory' for main:Object (NameError) 而不是返回error!
如果Thread.new {} 没有包裹在each {} 中,则块被正确救出。
这是为什么?在这种情况下如何正确拯救我的线程?

编辑:我发现将 begin-rescue-end 块包装在相同的块中会有所帮助。但是一个问题仍然存在——为什么一次救援还不够?

编辑:包装在另一个救援块中会有所帮助,但并非总是如此 - 有时它仍然无法救援。

【问题讨论】:

    标签: ruby multithreading rescue


    【解决方案1】:

    您所写的内容存在一些问题,我认为这些问题对您造成了影响。

    1. 您不应该设置Thread.abort_on_exception = true,除非您真的希望程序在辅助线程中发生异常时中止。通常,您只希望将此设置为 true 以进行调试。如果设置为 false,线程中引发的任何异常都将导致该线程退出,但只有在您使用子线程join 时才会对父线程可见。

    2. 在上面的代码中,当您尝试加入线程时,变量a 超出范围。因此,您也应该在那里获得NameError

    3. 即使这在范围内,您也只是加入其中一个线程。

    您应该发现以下更可预测:

    Thread.abort_on_exception = false
    
    begin
      threads = [1, 2].collect do |i|
        Thread.new do
          errory
        end
      end
      threads.each { |thread| thread.join } # You might want to use a ThreadsWait here instead.
    rescue Exception
      puts 'error!'
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-24
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      相关资源
      最近更新 更多