Я думаю, что сталкиваюсь с фундаментальным неверным толкованием с моей стороны того, как, распараллеливая работы в рубине и я надеюсь получить некоторое понимание.
Я хотел бы иметь простого производителя и потребителя. Во-первых, поток производителя, который вытягивает строки из файла и засовывает их в 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
Теперь несколько потребителей. Для простоты давайте сделаем, чтобы они ничего не сделали.
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 (рубин 1.9.1p243 (16.07.2009 пересмотров 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 trunk 24705) [i386-darwin10.0.0])