介绍性 Ruby 线程问题
Introductory Ruby Threading Issue
这几天一直在学习Ruby,在线程的实现上遇到了一些问题。我以前用其他语言编程过(主要是 Java 和 C),但我仍然无法弄清楚问题出在哪里。我在 Ubuntu 服务器 14.10 上运行 ruby 2.1.2p95。有问题的代码来自 Mr. Neighborly's 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, which used green threads。 Ruby 1.9 及更高版本使用 native 线程(线程由 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 中那样具有确定性,OS 可以随意忽略对 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>'
这几天一直在学习Ruby,在线程的实现上遇到了一些问题。我以前用其他语言编程过(主要是 Java 和 C),但我仍然无法弄清楚问题出在哪里。我在 Ubuntu 服务器 14.10 上运行 ruby 2.1.2p95。有问题的代码来自 Mr. Neighborly's 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, which used green threads。 Ruby 1.9 及更高版本使用 native 线程(线程由 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 中那样具有确定性,OS 可以随意忽略对 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>'