4

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

Ruby 多个后台线程

并添加一行:

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 挂断(暂停主线程)。为什么?这不是反对并发吗?帮助澄清我的想法?

4

2 回答 2

2

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

如果您将 join 语句移动到文件的最后,然后在其后面加上:

puts 'main_thread joined!'

你会看到的:

main_thread
thread_1
main_thread joined!
于 2013-06-18T15:17:01.213 回答
0

RubyThread#join方法使调用线程阻塞,直到目标线程完成,允许您“检查点”多个线程。

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

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

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

于 2013-06-18T15:18:42.250 回答