Penso di essere di fronte a un malinteso fondamentale da parte mia sul modo in cui il threading funziona in ruby e spero di ottenere qualche intuizione.Deadlock in ruby code usando SizedQueue
Mi piacerebbe avere un semplice produttore e consumatore. Innanzitutto, un thread del produttore che estrae le righe da un file e le inserisce in un SizedQueue; quando quelli finiscono, attaccare alcuni token alla fine per consentire al consumatore (s) sapere che le cose sono fatte.
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
Ora alcuni consumatori. Per semplicità, facciamoli fare niente.
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"
mia comprensione è che (a) il filo produttore bloccherà una volta che la SizedQueue è piena e infine tornare a riempirlo, e (b) i fili di consumo tirerà dalla SizedQueue, bloccando quando si svuota e alla fine finire.
Ma sotto ruby1.9 (ruby 1.9.1p243 (revisione 2009-07-16 24175) [i386-darwin9]) Ottengo un errore deadlock sui join. Cosa sta succedendo qui? Semplicemente non vedo dove ci sia un'interazione tra i thread tranne tramite SizedQueue, che dovrebbe essere thread-safe.
Qualsiasi intuizione sarebbe molto apprezzata.
Eccellente. Verificato che funzioni con un recente trunk da 1.9. Grazie! –
Nessun problema. Dovresti quindi "accettare" la risposta cliccando sul segno di spunta. –