2013-03-26 13 views
5

テキストファイルを解析してデータを並行してダウンロードするプログラムを作成しました。 9つ以下のスレッドでメソッドをダウンロードすると、プログラムにエラーが発生しません。しかし、10以上のスレッドでメソッドを実行すると、プログラムは "初期化"をスローします。getaddrinfo:名前またはサービスが不明(SocketError) "というエラーです。私はいくつかのアルゴリズムを並行して実行しようとしましたが、同じ問題が発生します。 「名前またはサービスが不明」のエラーが発生したときに、「オープン」メソッド(open-uri)に渡されたURLをブラウザに入れ、このURLが有効で正しいデータを受信したことを確認しました。多くのスレッドで "Name or service not known(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時間後に、私は一時的な解決策を見つけました。 「開始」〜「レスキュー〜リトライ〜終了」の「リクエスト」メソッドで「オープン」メソッドを挟んだ場合、2回目の「オープン」が呼び出されたときにエラーは発生しません。ここにコードがあります。

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

例外をキャッチし、URLと「再試行」を表示した後、URLおよび「再試行」が表示されることはありませんし、プログラムが正しく動作:) しかし、それでもまだ、私はこの問題の原因を見つけることができません。

+0

'require 'socket'を実行するとどうなりますか?あなたのURLにSocket.getaddrinfo( "www.example.com"、 "http") '? –

+0

ローカルURLを使用している可能性があります。 'localhost'です。 '127.0.0.1'とスワップしてみてください –

+0

@paddeこれは基本的な検索の問題です - 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 
関連する問題