我想我遇到了一个基本的误解,关于Ruby中线程是如何工作的,我希望能得到一些见解。
我想要一个简单的生产者和消费者。首先,一个生产者线程,它从一个文件中提取行,并将它们粘贴到一个大小合适的队列中;当这些行用完时,在末尾粘贴一些令牌,让消费者知道事情已经完成。
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(ruby1.9.1p243(2009-07-16版本24175)[i386-darwin9])下,连接上会出现死锁错误。这是怎么回事?我只是不知道线程之间的交互在哪里,除了通过sizedqueue,它应该是线程安全的。
任何见解都会受到赞赏。