介绍性Ruby线程问题

我过去几天一直在学习
Ruby,而且我遇到了一些关于线程实现的问题.我以前用其他语言编程(主要是Java和C),我仍然无法弄清楚问题是什么.我在Ubuntu Server 14.10上运行ruby 2.1.2p95.有问题的代码来自Mr. Neighborly的Humble Little Ruby Book:

mate = Thread.new do
  puts "Ahoy! Can I be dropping the anchor sir?"
  Thread.stop
  puts "Aye sir, dropping anchor!"
end

Thread.pass

puts "CAPTAIN: Aye, laddy!"

mate.run
mate.join

输出应该是:

Ahoy! Can I be dropping the anchor sir?
CAPTAIN: Aye, laddy!
Aye sir, dropping anchor!

但相反,我收到以下连接和死锁错误:

CAPTAIN: Aye, laddy!
Ahoy! Can I be dropping the anchor sir?
ex2.rb:12:in `join': No live threads left. Deadlock? (fatal)
    from ex2.rb:12:in `<main>'

我也遇到了来自其他资源的其他线程示例的错误,并尝试在其他Ubuntu机器上运行示例以及尝试使用Ruby 2.2.是否有一个我错过的明目张胆的概念?在最近的Ruby修订版本中有什么变化可以认为这些例子已经过时了吗?谢谢您的帮助!

最佳答案

Has something changed in recent revisions of Ruby that would deem the examples out-of-date?

是.看起来这本书是written for Ruby 1.8,它使用了green threads. Ruby 1.9以后使用本机线程(线程由OS调度).

比较Thread.pass method in Ruby 1.8.7的文档:

Invokes the thread scheduler to pass execution to another thread.

在Ruby 2.1.2(您使用的版本)中,this methods documentation如下所示:

Give the thread scheduler a hint to pass execution to another thread. A running thread may or may not switch, it depends on OS and processor.

所以在当前版本中,调度不像Ruby 1.8.7那样是确定性的,操作系统可以自由地忽略对Thread.pass的调用并首先运行主线程,这会导致问题.

在我的机器上运行这个脚本(Mac OS 10.9,Ruby 2.2.0)我得到了两个结果,有时它可以工作,我看到:

Ahoy! Can I be dropping the anchor sir?
CAPTAIN: Aye, laddy!
Aye sir, dropping anchor!

其他时候它失败了:

CAPTAIN: Aye, laddy!
Ahoy! Can I be dropping the anchor sir?
capt-thread.rb:12:in `join': No live threads left. Deadlock? (fatal)
    from capt-thread.rb:12:in `<main>'
点赞