Ruby线程中的.join有什么意义?

时间:2013-06-18 15:11:37

标签: ruby concurrency

让我们从这个问题中获取此代码:

Ruby multiple background threads

并添加一行:

require 'thread'

def foo(&block)
  bar(block)
end

def bar(block)
  Thread.abort_on_exception=true
  @main = Thread.new { block.call }
end


foo {
sleep 2
puts 'thread_1'
}.join

puts 'main_thread'

这是我得到的输出:

thread_1
main_thread

对于许多人来说,这看起来似乎很合理,但对我来说并非如此。 我在期待:

main_thread
thread_1

为什么呢?因为这就是我看待事物的方式

main_thread : ----------(starts thread_1)-(prints 'main_thread')--Done!

thread_1    :                           \-(sleeps 2 secs)----------(prints 'thread_1')--Done!

但这不会发生。如果我删除了.join部分,那么'thread_1'甚至都不显示。 从我的理解.join挂起(暂停主线程)。为什么?这不是针对并发吗?帮助澄清我的想法?

2 个答案:

答案 0 :(得分:2)

Thread#join在继续之前等待子线程完成,所以预期的结果确实是你所看到的。

如果将join语句移动到文件的最末端,然后按照以下步骤操作:

puts 'main_thread joined!'

你会看到:

main_thread
thread_1
main_thread joined!

答案 1 :(得分:0)

Ruby Thread#join method使调用线程阻塞,直到目标线程完成,允许您“检查”多个线程。

可以这样想,当你启动一个线程时,你从一行执行到两行,当你加入一个线程时,你会从两行执行到一行。

Thread#start             Thread#join
------+---->     ...     ------O--->
      \---->     ...     ------/

看起来很奇怪,但这是一种常见的情况。例如,假设您有一个线程在后台工作,另一个线程无法继续,直到该工作完成;在这种情况下,“join”是让线程协调其活动的简单方法。