ruby中的并行HTTP请求

我有一系列的URL,我不想打开每个URL并获取一个特定的标签。
但我想并行地做这件事。

这是我想要做的伪代码:

 urls = [...]
 tags = []
 urls.each do | url |
   fetch_tag_asynchronously(url)do | tag |
    标签<<标签
  结束
结束
 wait_for_all_requests_to_finish()

如果这可以以一种美妙而安全的方式完成,那将是非常棒的。
我可以使用线程,但它看起来不像数组在ruby中是线程安全的。

您可以使用Mutex实现线程安全:

 require 'thread' # for Mutex urls = %w( http://test1.example.org/ http://test2.example.org/ ... ) threads = [] tags = [] tags_mutex = Mutex.new urls.each do |url| threads << Thread.new(url, tags) do |url, tags| tag = fetch_tag(url) tags_mutex.synchronize { tags << tag } end end threads.each(&:join) 

然而,为每个URL使用一个新线程可能会适得其反,因此限制这样的线程数可能会更高效:

 THREAD_COUNT = 8 # tweak this number for maximum performance. tags = [] mutex = Mutex.new THREAD_COUNT.times.map { Thread.new(urls, tags) do |urls, tags| while url = mutex.synchronize { urls.pop } tag = fetch_tag(url) mutex.synchronize { tags << tag } end end }.each(&:join) 

Typhoeus / Hydragem组合设计非常容易。 它非常方便和强大。

感谢ruby的GIL,基于我阅读http://merbist.com/2011/02/22/concurrency-in-ruby-explained/以及更多链接,这应该是安全的。