如何加入ruby线程?

时间:2013-07-20 13:50:46

标签: ruby multithreading

在线程上调用join将阻止父线程,而要连接的线程尚未完成。为了检查这一点,我创建了这段代码:

threads = []
3.times do |i|
  threads << Thread.new do
    3.times do |j|
      puts "Thread #{i} says #{j} (#{Thread.current})"
      sleep 0.1
    end
  end
end

#threads.map(&:join)
threads[0].join
puts "After first join"
threads[1].join
puts "After second join"
threads[2].join
puts "Last line of main thread"

运行此类代码会产生以下输出:

Thread 0 says 0 (#<Thread:0x007fdceb0b8568>)
Thread 2 says 0 (#<Thread:0x007fdce982bb08>)
Thread 1 says 0 (#<Thread:0x007fdceb0b8450>)
Thread 0 says 1 (#<Thread:0x007fdceb0b8568>)
Thread 1 says 1 (#<Thread:0x007fdceb0b8450>)
Thread 2 says 1 (#<Thread:0x007fdce982bb08>)
Thread 1 says 2 (#<Thread:0x007fdceb0b8450>)
Thread 2 says 2 (#<Thread:0x007fdce982bb08>)
Thread 0 says 2 (#<Thread:0x007fdceb0b8568>)
After first join
After second join
Last line of main thread

为什么ruby在线程&#39;之后打印After first join。尽管指令threads[1].join是在此打印指令之后执行的?

1 个答案:

答案 0 :(得分:3)

因为puts "Thread #{i} says #{j} (#{Thread.current})" threads[1]部分(或可能全部)puts "After first join"threads[1].join之前完成。在puts "After first join"之后puts "Thread #{i} says #{j} (#{Thread.current})"执行的事实不会影响结果。

你似乎有两点逻辑缺陷。它们应该按如下方式纠正:

  • 如果threads[1]的{​​{1}}在主线程的puts "After first join"之前完成,那么整个threads[1]是否在puts "After first join"开始之前完成是无关紧要的。< / LI>
  • threads[1]有机会在主线程执行puts "After first join"之前完成。 threads[1].join仅显示效果。

可能发生的事情(实际发生的事情)是,因为在任何threads[0].join方法调用之前你有puts,所以主线程一直在睡眠,直到threads[0]完成。由于threads[1]threads[2]threads[0]之后立即启动,因此三个子线程大致几乎同时完成。换句话说,如果你等待threads[0]完成的时间足够长,那么其他两个线程很可能也会完成。