2014-12-16 41 views
5

mulithread sabit Uygulamalar hakklı ederken tespit edildi:.. Sabit Uygulamalar RuntimeError (Döngüsel bağımlılık bu hatayı alıyorum

Ben mulithread ediyorum hakklı ederken tespit RuntimeError (Dairesel bağımlılık İşte aşağıda benim kodudur neden oluyor ? Multithread çalışmamın nedeni, bir HTML kazıma uygulaması yazıyorum çünkü Nokogiri :: HTML (open()) çağrısı, geri dönmek için 1 saniye süren bir eşzamanlı engelleme çağrısıdır ve 100.000+ sayfa var ziyaret etmek için, bu sorunun üstesinden gelmek için birkaç iş parçacığı çalıştırmaya çalışıyorum. Bunu yapmanın daha iyi bir yolu var mı?

class ToolsController < ApplicationController 

def getWebsites 
    t1=Thread.new{func1()} 
    t2=Thread.new{func1()} 
    t3=Thread.new{func1()} 
    t4=Thread.new{func1()} 
    t5=Thread.new{func1()} 
    t6=Thread.new{func1()} 
    t1.join 
    t2.join 
    t3.join 
    t4.join 
    t5.join 
    t6.join 
end 

def func1 
    puts Thread.current 
    apps = Apps.order("RANDOM()").where("apps.website IS NULL").take(1) 
    while apps.size == 1 do 
     app = apps[0] 
     puts app.name 
     puts app.iTunes 
     doc = Nokogiri::HTML(open(app.iTunes)) 
     array = doc.css('div.app-links a').map { |link| 
      url = link['href'] 
      url = Domainatrix.parse(url) 
      url.domain + "." + url.public_suffix 
     } 
     array.uniq! 
     if (array.size > 0) 
      app.website = array.join(', ') 
      puts app.website 
     else 
      app.website = "NONE" 
     end 
     app.save 
     apps = Apps.order("RANDOM()").where("apps.website IS NULL").take(1) 
    end 
end 


end 
+0

Vay, burada yapmaya çalıştığınız şeyle başlayabilir miyiz? Bir denetleyicideki iş parçacıklarının atılması başarı için bir reçete gibi görünmüyor. Bu tür bir durum varsa, modelinizden bir ': type 'alanının kaldırılmasından söz eden bazı SO cevapları var mıdır? –

+0

@etayluz, paylaştığınız kod ne yapmak istediğinizi belirtmiyor. Belki de çok iş parçacığına ihtiyacınız yok. Eğer 6 tane rasgele 'uygulama' nesnesi almak istiyorsanız, o zaman, örneğin, 't1, t2 = Apps.order ("RANDOM()") yapın. Burada (koşullar) .limit (2) .to_a' 6 için modifikasyonlarla 2. – Humza

+1

yerine ve çok iş parçacığı kullanmanız gerekiyorsa, bunun "iş öneri" özelliği olmayan bir şeyle ilgili olabilir. t1 değişkeninizin atanmasından önce. do 't0 = Apps.first'. Dişler başlatılmadan önce gerekli şeyleri gerektirir. – Humza

cevap

8

"iste" evreli değil

Değişim yöntemlerinizi böylece ipler başlamadan önce öyle yapılır "gerekli" olan her şey. Örneğin

:

def get_websites 
    # values = Apps.all # try uncommenting this line if a second-try is required 

    ar = Apps.where("apps.website IS NULL") 

    t1 = Thread.new{ func1(ar) } 
    t2 = Thread.new{ func1(ar) } 

    t1.join 
    t2.join 
end 

def func1(ar) 
    apps = ar.order("RANDOM()").limit(1) 

    while (apps.size == 1) 
     puts Thread.current 
    end 
end 

Ama birileri belirttiği gibi, kumandanın içinde çoklu kullanım şekliniz tavsiye edilmez.

+0

Aynı problemim var .. Mutex sove olabilir mi? – JonatasTeixeira

İlgili konular