2013-03-26 3 views
5

텍스트 파일을 구문 분석하고 데이터를 병렬로 다운로드하는 프로그램을 만들었습니다. 9 이하의 스레드에서 다운로드 방법을 실행할 때 프로그램에 오류가 없습니다. 그러나 10 개 이상의 스레드에서 메소드를 실행하면 프로그램이 "초기화"됩니다. getaddrinfo : 이름 또는 서비스를 알 수 없음 (SocketError) "오류. 내가 병렬로 실행하는 몇 가지 알고리즘을 시도했지만 동일한 문제가 발생합니다. 브라우저에 "이름 또는 서비스를 알 수 없음"오류가 발생했을 때 '열린'방법 (open-uri)으로 전달 된 URL을 넣고이 URL이 유효하고 올바른 데이터를 수신했음을 확인했습니다. 부분 코드입니다.많은 스레드에서 실행될 때 "이름 또는 서비스를 알 수 없음 (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 시간 후에 임시 해결책을 찾았습니다. 'begin ~ rescue ~ retry ~ end'로 '요청'메소드에 'open'메소드를 끼운 경우 두 번째 'open'이 호출 될 때 오류가 발생하지 않습니다. 여기 코드가 있습니다. 예외를 잡기 및 URL과 "다시 시도", url 및 "다시 시도"를 표시 한 후

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

가 표시되지 않습니다 및 프로그램이 제대로 작동 :) 을하지만 여전히 나는이 문제의 원인을 찾을 수 없습니다.

+0

'require 'socket'을 시도하면 어떻게됩니까? 당신의 URL로 Socket.getaddrinfo ("www.example.com", "http")'? –

+0

예를 들어 로컬 URL을 사용하고 있습니다. 'localhost'. '127.0.0.1' –

+0

@ swade로 바꿔보십시오. 기본 검색 문제 인 것처럼 보이지 않습니다. OP는 9 개의 스레드에서 작동하지만 10에서는 작동하지 않는다고 말했습니다. –

답변

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