介绍性Ruby线程问题

时间:2015-01-04 20:20:12

标签: ruby multithreading

过去几天我一直在学习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修订版本中有什么变化可以认为这些例子已经过时了吗?谢谢你的帮助!

1 个答案:

答案 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>'
相关问题