2013-07-13 107 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块,以避免访问内数据同时在多个线程中。

相关问题