使用SizedQueue在ruby代码中死锁

Bil*_*ber 6 ruby queue multithreading deadlock

我认为我遇到了一个基本的误解,就我在红宝石中如何处理线程而言,我希望得到一些见解.

我想拥有一个简单的制作人和消费者.首先,一个生产者线程从文件中提取线条并将它们粘贴到SizedQueue中; 当那些用完时,最后贴上一些令牌让消费者知道事情已经完成.

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
Run Code Online (Sandbox Code Playgroud)

现在有几个消费者.为简单起见,我们让他们什么都不做.

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"
Run Code Online (Sandbox Code Playgroud)

我的理解是(a)一旦SizedQueue已满,生产者线程将阻塞并最终回到填充状态,并且(b)消费者线程将从SizedQueue中拉出,在它清空时阻塞,并最终完成.

但是在ruby1.9下(ruby 1.9.1p243(2009-07-16修订版24175)[i386-darwin9])我在连接上遇到死锁错误.这里发生了什么?我只是没有看到线程之间的任何交互,除了通过SizedQueue,它应该是线程安全的.

任何见解都会受到高度赞赏.

Mar*_*une 3

您的理解是正确的,您的代码可以在我的机器上运行,在较新版本的 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])