2013-07-13 76 views
1

我想在Ruby中發出多個HTTP請求。我知道它可以很容易地在NodeJS中完成。我正在嘗試在Ruby中使用線程來完成它,但我不知道這是否是最好的方法。我沒有成功運行大量的請求(例如超過50)。有沒有更好的方法在Ruby中異步執行多個HTTP請求?

require 'json' 
require 'net/http' 

urls = [ 
    {"link" => "url1"}, 
    {"link" => "url2"}, 
    {"link" => "url3"} 
] 

urls.each_value do |thing| 
    Thread.new do 
     result = Net::HTTP.get(URI.parse(thing)) 
     json_stuff = JSON::parse(result) 
     info = json["person"]["bio"]["info"] 

     thing["name"] = info 
    end 
end 

# Wait until threads are done. 
while !urls.all? { |url| url.has_key? "name" }; end 

puts urls 

有什麼想法?

回答

1

相反,你使用,你可以調用線程#的,而條款的加入,使主線程等待其他線程。

threads = [] 
urls.each_value do |thing| 
    threads << Thread.new do 
     result = Net::HTTP.get(URI.parse(thing)) 
     json_stuff = JSON::parse(result) 
     info = json["person"]["bio"]["info"] 

     thing["name"] = info 
    end 
end 

# Wait until threads are done. 
threads.each { |aThread| aThread.join } 
1

你的方式可能會奏效,但它會在一個繁忙的循環結束了,吃了CPU週期時它真的不需要。更好的方法是僅在請求完成時檢查您是否完成。一種方法是使用MutexConditionVariable

使用互斥和條件變量,我們可以有主線程等待,而當工作線程接收它的響應,它可以喚醒主線程。然後,主線程可以查看是否有任何URL需要下載;如果是這樣,它就會再次入睡,等待;否則,就完成了。

等待一個信號:

mutex.synchronize { cv.wait mutex } 

要喚醒等待的線程:

mutex.synchronize { cv.signal } 

你可能要檢查所做的煩躁和設置thing['name']mutex.synchronize塊,以避免訪問內數據同時在多個線程中。

相關問題