2010-03-10 7 views
5

kullanarak ruby ​​kod kilitlenme Ben ruby ​​içinde nasıl iş parçacığı nasıl bir temel yanlış anlama karşı koşuyorum düşünüyorum ve biraz anlayış elde etmeyi umuyoruz.SizedQueue

Basit bir üretici ve tüketiciye sahip olmak isterim. İlk olarak, bir dosyadan satırları çeken ve bunları bir SizedQueue'a yapıştıran bir üretici iş parçacığı; Tüketiciler bittiğinde, tüketicinin (şeylerin) bildiklerini bilmesine izin vermek için bazı belirteçleri yapıştırın.

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 

Şimdi birkaç tüketici. Basitlik için, onlara hiçbir şey yapmasın.

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" 

Benim anlayış, (a) SizedQueue kez engeller yapımcı iplik (b) Tüketici ipler o boşaltır engelleme, SizedQueue dan çeker dolu ve sonunda onu dolduruyor geri almak ve olmasıdır ve sonunda bitirin.

Ama ruby1.9 altında (ruby 1.9.1p243 (2009-07-16 düzeltme 24175) [i386-darwin9]) Katılmalarda bir kilitlenme hatası alıyorum. Burada neler oluyor? Ben sadece iş parçacığı güvenli olması gerekiyordu SizedQueue dışında threadler arasında herhangi bir etkileşim olduğunu görmüyorum.

Herhangi bir fikir çok takdir edilecektir.

cevap

3

Anlayışınız doğru ve kodunuz makinemde biraz daha yeni bir Ruby sürümünde çalışıyor (her ikisi de 1.9.2dev (2009-08-30 trunk 24705) [i386-darwin10.0.0] ve ruby ​​1.9.2dev (2009-08-30 gövde 24705) [i386 darwin10.0.0])

+0

mükemmel. Yakın bir 1.9 trunk ile çalıştığını doğruladı. Teşekkürler! –

+0

Sorun değil. Daha sonra, onay işaretini tıklayarak cevabı "kabul etmelisiniz". –