处理在Ruby线程中引发的异常 [英] Handling exceptions raised in a Ruby thread
问题描述
def foo(n)
putsfor#{n}$ b $
开始
线程= []
[5,15,20,3] |我| |
线程<< Thread.new do
foo(i)
end
end
threads.each(&:join)
rescue Exception => e
放EXCEPTION:#{e.inspect}
putsMESSAGE:#{e.message}
end
此代码在5秒钟后捕获异常。
但是,如果将数组更改为 [15,5,20,3]
,上面的代码在15秒后捕获异常。总之,它总是捕获第一个线程中引发的异常。
任何想法,为什么这样。为什么每次3秒钟后都不能捕获异常?如何捕获任何线程的第一个引发的异常?
如果您希望任何线程中的任何未处理的异常导致解释器要退出,您需要设置主题:: abort_on_exception = 到 true
。未处理的异常导致线程停止运行。如果您不将此变量设置为true,则只会在调用 Thread#join
或 Thread#value
为线程。如果设置为true,它将在它发生时被提升,并将传播到主线程。
Thread.abort_on_exception = true#add
def foo(n)
放入for#{n}
sleep n
raiseafter#{n}
end
begin
threads = []
[15,5,20,3] .each do | i |
线程<< Thread.new do
foo(i)
end
end
threads.each(&:join)
rescue Exception => e
放EXCEPTION:#{e.inspect}
putsMESSAGE:#{e.message}
end
输出:
5
为20
为3
为15
EXCEPTION:#< RuntimeError:after 3>
MESSAGE:after 3
注意:但是如果您希望任何特定的线程实例引发异常这样就有类似的 abort_on_exception =线程实例方法:
t = Thread.new {
#执行某些操作并引发异常
}
t.abort_on_exception =真
I am looking for a solution of classic problem of exception handling. Consider following piece of code:
def foo(n)
puts " for #{n}"
sleep n
raise "after #{n}"
end
begin
threads = []
[5, 15, 20, 3].each do |i|
threads << Thread.new do
foo(i)
end
end
threads.each(&:join)
rescue Exception => e
puts "EXCEPTION: #{e.inspect}"
puts "MESSAGE: #{e.message}"
end
This code catches the exception after 5 seconds.
But if I change the array as [15, 5, 20, 3]
, above code catch the exception after 15 seconds. In short, it always catch the exception raised in first thread.
Any idea, why so. Why doesn't it catch the exception after 3 seconds each time? How do I catch the first raised exception by any thread?
If you want any unhandled exception in any thread to cause the interpreter to exit, you need to set Thread::abort_on_exception= to true
. Unhandled exception cause the thread to stop running. If you don't set this variable to true, exception will only be raised when you call Thread#join
or Thread#value
for the thread. If set to true it will be raised when it occurs and will propagate to the main thread.
Thread.abort_on_exception=true # add this
def foo(n)
puts " for #{n}"
sleep n
raise "after #{n}"
end
begin
threads = []
[15, 5, 20, 3].each do |i|
threads << Thread.new do
foo(i)
end
end
threads.each(&:join)
rescue Exception => e
puts "EXCEPTION: #{e.inspect}"
puts "MESSAGE: #{e.message}"
end
Output:
for 5
for 20
for 3
for 15
EXCEPTION: #<RuntimeError: after 3>
MESSAGE: after 3
Note: but if you want any particular thread instance to raise exception this way there are similar abort_on_exception= Thread instance method:
t = Thread.new {
# do something and raise exception
}
t.abort_on_exception = true
这篇关于处理在Ruby线程中引发的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!