2013-03-26 53 views
5

我製作了一個程序,用於分析文本文件並以並行方式下載數據。當在9個或更少的線程中運行下載方法時,程序沒有錯誤。但是,當在10個或更多線程中運行該方法時,程序將拋出「`initialize':getaddrinfo:名稱或服務未知(SocketError)」錯誤。我嘗試了一些算法並行運行,但同樣的問題發生。 我把URL傳遞給'打開'方法(open-uri),當「名稱或服務未知」錯誤發生時,瀏覽器並確認這個URL是有效的,並收到正確的data.Here的部分代碼。在許多線程中運行時出現「名稱或服務未知(SocketError)」錯誤

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 

和錯誤是

/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>' 

爲什麼會出現這種情況?有沒有人遇到類似的問題? 請幫幫我!

第一個問題後3小時,我找到了臨時解決方案。 如果我在「請求」方法中將'open'方法與'begin〜rescue〜retry〜end'夾在一起,那麼第二次'open'調用時就不會發生錯誤。這裏是代碼。

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

捕捉異常並顯示URL和「重試」,URL和「重試」後,將永遠不會被顯示,程序正常工作:) 但仍然無法找到是什麼原因導致這個問題。

+0

如果您嘗試'require'socket',會發生什麼?使用您的URL的Socket.getaddrinfo(「www.example.com」,「http」)'? – 2013-03-26 09:14:15

+0

也許您正在使用本地URL 'localhost'。嘗試與'127.0.0.1'交換 – 2013-03-26 09:14:58

+0

@padde它看起來不像這是一個基本的查找問題 - OP提到它可以使用9個線程,但不能使用10. – 2013-03-26 09:30:41

回答

3

我想這可能是因爲線程之間的競爭條件。嘗試以原子方式執行操作。放置互斥鎖。

@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 
相關問題