2

我正在尝试在 Ruby 中发出多个 HTTP 请求。我知道它可以很容易地在 NodeJS 中完成。我正在尝试使用线程在 Ruby 中执行此操作,但我不知道这是否是最好的方法。我还没有成功运行大量请求(例如超过 50 个)。

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

有什么想法吗?

4

2 回答 2

3

代替您使用的 while 子句,您可以调用 Thread#join 以使主线程等待其他线程。

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 }
于 2013-07-13T12:25:00.723 回答
2

你的方法可能有效,但它最终会进入一个繁忙的循环,当它真的不需要时会占用 CPU 周期。更好的方法是仅在请求完成时检查您是否已完成。实现此目的的一种方法是使用 aMutex和 a ConditionVariable

使用互斥锁和条件变量,我们可以让主线程等待,当其中一个工作线程收到它的响应时,它可以唤醒主线程。然后主线程可以查看是否有任何 URL 需要下载;如果是这样,它将再次进入睡眠状态,等待;否则,它就完成了。

等待信号:

mutex.synchronize { cv.wait mutex }

唤醒等待线程:

mutex.synchronize { cv.signal }

您可能需要检查完成情况并thing['name']mutex.synchronize块内设置以避免同时访问多个线程中的数据。

于 2013-07-13T05:56:34.650 回答