2013-03-26 30 views
5

Tôi đã thực hiện một chương trình phân tích cú pháp tệp văn bản và tải xuống dữ liệu song song. Khi chạy phương thức tải xuống trong chuỗi 9 hoặc ít hơn, chương trình không có lỗi. Nhưng khi chạy phương thức trong 10 hoặc nhiều luồng, chương trình sẽ ném "` khởi tạo ": getaddrinfo: Lỗi tên hoặc dịch vụ không biết (SocketError)". Tôi đã thử một số thuật toán để chạy song song, nhưng cùng một vấn đề xảy ra. Tôi đặt url, được chuyển tới phương thức 'mở' (open-uri) khi lỗi "Tên hoặc dịch vụ không xác định" xảy ra, vào trình duyệt và xác nhận rằng url này hợp lệ và nhận được mã dữ liệu chính xác.Lỗi "Tên hoặc dịch vụ không xác định (SocketError)" khi chạy trong nhiều chủ đề

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 

và lỗi là

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

Tại sao điều này xảy ra? Có ai gặp phải vấn đề tương tự không? Xin hãy giúp tôi!

3 giờ sau câu hỏi đầu tiên, tôi tìm thấy giải pháp tạm thời. Nếu tôi kẹp 'phương pháp' mở trong phương thức 'yêu cầu' với 'bắt đầu ~ giải cứu ~ thử lại ~ kết thúc', lỗi không xảy ra khi lần thứ hai 'mở' được gọi là. Đó là mã.

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

Sau khi bắt ngoại lệ và hiển thị url và "thử", url và "thử" sẽ không bao giờ được hiển thị và các chương trình hoạt động chính xác :) Nhưng tôi vẫn không thể tìm thấy những gì gây ra vấn đề này.

+0

Điều gì xảy ra nếu bạn thử 'socket 'yêu cầu'; Socket.getaddrinfo ("www.example.com", "http") 'với URL của bạn? –

+0

Có thể bạn đang sử dụng URL địa phương, ví dụ: 'localhost'. Hãy thử trao đổi với '127.0.0.1' –

+0

@padde nó không giống như thế này là một vấn đề tra cứu cơ bản - OP đề cập rằng nó hoạt động với 9 chủ đề nhưng không phải với 10. –

Trả lời

3

Tôi nghĩ rằng đó có thể là do tình trạng cuộc đua giữa các chủ đề. Hãy thử thực hiện các hoạt động một cách nguyên tử. Đặt khóa mutex.

@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 
Các vấn đề liên quan