我认为我对线程在 ruby 中的工作原理存在根本性的误解,我希望获得一些见解。
我想要一个简单的生产者和消费者。首先,生产者线程从文件中提取行并将它们粘贴到 SizedQueue 中;当那些用完时,在末端贴上一些 token ,让消费者知道事情已经完成。
require 'thread'
numthreads = 2
filename = 'edition-2009-09-11.txt'
bq = SizedQueue.new(4)
producerthread = Thread.new(bq) do |queue|
File.open(filename) do |f|
f.each do |r|
queue << r
end
end
numthreads.times do
queue << :end_of_producer
end
end
现在有几个消费者。为简单起见,让他们什么都不做。
consumerthreads = []
numthreads.times do
consumerthreads << Thread.new(bq) do |queue|
until (line = queue.pop) === :end_of_producer
# do stuff in here
end
end
end
producerthread.join
consumerthreads.each {|t| t.join}
puts "All done"
我的理解是 (a) 一旦 SizedQueue 已满,生产者线程将阻塞并最终返回填充它,并且 (b) 消费者线程将从 SizedQueue 中拉出,在它清空时阻塞,并最终完成.
但是在 ruby1.9(ruby 1.9.1p243(2009-07-16 修订版 24175)[i386-darwin9])下,我在连接上遇到死锁错误。这里发生了什么?除了 SizedQueue,我只是看不到线程之间的任何交互,它应该是线程安全的。
如有任何见解,我们将不胜感激。
最佳答案
你的理解是正确的,你的代码可以在我的机器上运行,在稍微更新的 Ruby 版本(ruby 1.9.2dev (2009-08-30 trunk 24705) [i386-darwin10.0.0] 和 ruby 1.9.2dev ( 2009-08-30 主干 24705) [i386-darwin10.0.0])
关于ruby - 使用 SizedQueue 在 ruby 代码中出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2414905/