3

我对 ruby​​ 多线程相当陌生,对如何开始感到困惑。我目前正在构建一个应用程序,它需要获取很多图像,所以我想在不同的线程中进行。我希望程序按照下面的代码执行。

问题:我在这里看到的问题是 bar_method 将更快地完成获取并且线程将结束,因此事情将继续添加到队列中但不会被处理。是否有任何可能的同步方式可以提醒 bar_method 线程新项目已添加到队列中,如果 bar_method 确实提前完成,它应该进入睡眠状态并等待新项目添加到队列中?

def foo_method 
  queue created - consists of url to fetch and a callback method
  synch = Mutex.new
  Thread.new do
    bar_method synch, queue 
  end
  100000.times do
    synch.synchronize do
      queue << {url => img_url, method_callback => the_callback}
    end
  end
end
def bar_method synch_obj, queue
  synch_obj.synchronize do
    while queue isn't empty
        pop the queue. fetch image and call the callback
    end   
  end
end 
4

1 回答 1

2

如果您需要从 Internet 检索文件并使用并行请求,我强烈推荐Typhoeus 和 Hydra

从文档中:

hydra = Typhoeus::Hydra.new
10.times.map{ hydra.queue(Typhoeus::Request.new("www.example.com", followlocation: true)) }
hydra.run

您可以在 Hydra 中设置并发连接数:

:max_concurrency (Integer) — 要创建的最大并发连接数。默认值为 200。

作为第二个建议,请查看Curb。同样,从其文档中:

# make multiple GET requests
easy_options = {:follow_location => true}
multi_options = {:pipeline => true}

Curl::Multi.get('url1','url2','url3','url4','url5', easy_options, multi_options) do|easy|
  # do something interesting with the easy response
  puts easy.last_effective_url
end

两者都建立在 Curl 之上,因此它们的底层技术或其稳健性没有真正的区别。不同之处在于您可以使用的命令。

另一个备受关注的宝石是 EventMachine。它具有允许并发请求的 EM-HTTP-Request :

EventMachine.run {
  http1 = EventMachine::HttpRequest.new('http://google.com/').get
  http2 = EventMachine::HttpRequest.new('http://yahoo.com/').get

  http1.callback { }
  http2.callback { } 
end
于 2013-01-05T01:35:13.070 回答