2013-03-26 11 views
5

Ich habe ein Programm erstellt, das Textdatei analysiert und Daten parallel herunterladen. Wenn die Download-Methode in 9 oder weniger Threads ausgeführt wird, hat das Programm keinen Fehler. Aber wenn die Methode in 10 oder mehr Threads ausgeführt wird, löst das Programm den Fehler "` initialize ': getaddrinfo: Name oder Dienst nicht bekannt (SocketError) "aus. Ich habe versucht, einige Algorithmen parallel zu laufen, aber das gleiche Problem tritt auf. Ich legte die URL, die an "offene" Methode übergeben wurde (Open-Uri), wenn "Name oder Service nicht bekannt" Fehler passiert, in den Browser und bestätigt, dass diese URL gültig ist und korrekte Daten erhalten. Hier ist Teilcode."Name oder Dienst nicht bekannt (SocketError)" Fehler beim Ausführen in vielen Threads

jobs = [] 
aps = [] 
.... 
#jobs are pushed into jobs[] 
.... 
max_thread = 15 
loop do 
    ary_threads = [] 
    max_thread.times do |i| 
    break if jobs.size == 0 
    job = jobs.pop 
    ary_threads << Thread.start { 
     begin 
     request(job[0],job[1]).each do |ap| #in "request" method, open(url)are called 
      aps.push(ap) 
     end 
     end 
    } 
end 
ary_threads.each { |th| th.join } 
break if jobs.size == 0 
end 

und Fehler ist

/usr/lib/ruby/1.9.1/net/http.rb:762:in `initialize': getaddrinfo: Name or service not known (SocketError) 
from /usr/lib/ruby/1.9.1/net/http.rb:762:in `open' 
from /usr/lib/ruby/1.9.1/net/http.rb:762:in `block in connect' 
from /usr/lib/ruby/1.9.1/timeout.rb:54:in `timeout' 
from /usr/lib/ruby/1.9.1/timeout.rb:99:in `timeout' 
from /usr/lib/ruby/1.9.1/net/http.rb:762:in `connect' 
from /usr/lib/ruby/1.9.1/net/http.rb:755:in `do_start' 
from /usr/lib/ruby/1.9.1/net/http.rb:744:in `start' 
from /usr/lib/ruby/1.9.1/open-uri.rb:306:in `open_http' 
from /usr/lib/ruby/1.9.1/open-uri.rb:775:in `buffer_open' 
from /usr/lib/ruby/1.9.1/open-uri.rb:203:in `block in open_loop' 
from /usr/lib/ruby/1.9.1/open-uri.rb:201:in `catch' 
from /usr/lib/ruby/1.9.1/open-uri.rb:201:in `open_loop' 
from /usr/lib/ruby/1.9.1/open-uri.rb:146:in `open_uri' 
from /var/lib/gems/1.9.1/gems/open-uri-cached-0.0.5/lib/open-uri/cached.rb:10:in `open_uri' 
from /usr/lib/ruby/1.9.1/open-uri.rb:677:in `open' 
from /usr/lib/ruby/1.9.1/open-uri.rb:33:in `open' 
from Test1.rb:42:in `request' 
from Test1.rb:77:in `block (3 levels) in <main>' 

Warum passiert das das? Hat jemand ein ähnliches Problem festgestellt? Bitte helfen Sie mir!

3 Stunden nach der ersten Frage fand ich eine vorübergehende Lösung. Wenn ich 'offene' Methode in 'Anfrage' -Methode mit 'begin ~ rescue ~ retry ~ end' einklemmte, tritt der Fehler nicht auf, wenn das zweite Mal 'open' aufgerufen. Hier ist der Code.

begin 
    response = open(url) 
rescue Exception 
    puts url 
    puts "retrying" 
    retry 
end 

Nach Ausnahme abfangen und URL und „erneuten Versuch“, die URL und „retrying“ Anzeige wird nie richtig funktioniert angezeigt und das Programm wird :) Aber noch kann ich nicht finden, was dieses Problem verursacht.

+0

Was passiert, wenn Sie 'require' Socket versuchen '; Socket.getaddrinfo ("www.beispiel.com", "http") 'mit Ihrer URL? –

+0

Möglicherweise verwenden Sie eine lokale URL, z. 'localhost'. Versuchen Sie, mit '127.0.0.1' –

+0

@padde swapping es sieht nicht aus wie dies ist ein grundlegendes Nachschlageproblem - das OP erwähnt, dass es mit 9 Threads funktioniert, aber nicht mit 10. –

Antwort

3

Ich denke, es könnte wegen Race Condition zwischen Threads sein. Versuchen Sie, die Operationen atomar auszuführen. Setzen Sie das Mutex-Schloss.

@mutex = Mutex.new 

    @mutex.syncronize do 
     ... 

     ary_threads << Thread.start { 
     begin 
     request(job[0],job[1]).each do |ap| #in "request" method, open(url)are called 
      aps.push(ap) 
     end 
     end 
     } 

     ... 
    end