ruby线程代码段的意外行为

时间:2015-01-19 12:34:26

标签: ruby multithreading

我正在尝试学习ruby中的线程,我正在执行以下代码:

Thread.abort_on_exception = true

threads = 5.times.map do |i|
    Thread.new(i) do |j|
        raise "Boom!" if j == 1
        print "#{j}\n"
    end
end

i=0
loop do
    i+=1
    puts "Waiting!!" if i == 10000
    break if i == 10**4
end

threads.each do |th|
    begin
        th.join
    rescue RuntimeError => e
        puts e
    end
end

puts "Done!!"

有时它会毫无例外地完美运行,并显示如下输出:

Waiting!!
0
2
3
4
Boom!
Boom!
Done!!

有时会退出异常并显示输出:

0
2
3
4
threading.rb:5:in `block (2 levels) in <main>': Boom! (RuntimeError)

现在我的问题是:

  1. 为什么?当我已经救出它时,它会退出RuntimeError。
  2. 怎么会有两个轰!在输出中。
  3. 开发环境:

    • Windows 7(x64)
    • Ruby 2.1.5

1 个答案:

答案 0 :(得分:1)

主线程到达具有Thread#join调用的块之前的线程中发生异常;特别是在你的循环中。问题在于,除了冒泡到主线程之外,它可以在任何代码行上发生;因此,您还需要在线程中封装错误处理。也许它可以返回一个错误值,但是在使用这个并发模型时,异常会从根本上被打破。

(要向自己证明这一点,请尝试在文件顶部设置$DEBUG = true;这会显示异常的确实位置。)