我过去几天一直在学习
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>'