过去几天我一直在学习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修订版本中有什么变化可以认为这些例子已经过时了吗?谢谢你的帮助!
答案 0 :(得分:2)
最近的Ruby修订版中是否有些内容发生了变化,认为这些示例已经过时了?
是。看起来这本书是written for Ruby 1.8,使用了green threads。 Ruby 1.9以后使用本机线程(线程由操作系统调度)。
比较Thread.pass
method in Ruby 1.8.7的文档:
调用线程调度程序将执行传递给另一个线程。
在Ruby 2.1.2(您使用的版本)中,this methods documentation如下所示:
为线程调度程序提供一个提示,将执行传递给另一个线程。正在运行的线程可能会切换也可能不会切换,这取决于操作系统和处理器。
因此,在当前版本中,调度不像Ruby 1.8.7那样具有确定性,操作系统可以自由地忽略对Thread.pass
的调用并首先运行主线程,这会导致问题。 / p>
在我的机器上运行此脚本(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>'