确定红宝石线状态

时间:2012-10-20 17:20:27

标签: ruby multithreading web-scraping

我有一个Ruby脚本使用线程通过HTTP获取HTML页面:

require "thread"
require "net/http"

q = Queue.new
q << "http://google.com/"
q << "http://rubygems.org/"
q << "http://twitter.com/"
t = Thread.new do
  loop do
    html = Net::HTTP.get(URI(q.pop))
    p html.length
  end
end

10.times do
  puts t.status
  sleep 0.3
end

我正在尝试确定线程在从给定源获取内容时的状态。这是我得到的输出:

run
219
sleep
sleep
7255
sleep
sleep
sleep
sleep
sleep
sleep
65446
sleep

线程几乎一直处于“睡眠”状态,尽管它实际上正在工作。我知道它正在等待HTTP类检索内容。最后一次“睡眠”是不同的:线程试图从队列中弹出值为空,并切换到“睡眠”状态,直到队列中有新的东西。

我希望能够检查线程中发生了什么:它是在HTTP上运行还是只是等待新作业出现?

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:4)

sleep 状态似乎涵盖了I / O等待和同步被阻止,因此您将无法使用线程状态来了解您是在处理还是在等待。相反,您可以使用线程本地存储来为线程进行通信。使用Thread#[]=存储值,使用Thread#[]将其恢复。

require "thread"
require "net/http"

q = Queue.new
q << "http://google.com/"
q << "http://rubygems.org/"
q << "http://twitter.com/"
t = Thread.new do
  loop do
    Thread.current[:status] = 'waiting'
    request = q.pop
    Thread.current[:status] = 'fetching'
    html = Net::HTTP.get(URI(request))
    Thread.current[:status] = 'processing'
    # Take half a second to process it.
    Time.new.tap { |start_time| while Time.now - start_time < 0.5 ; end }
    p html.length
  end
end

10.times do
  puts t[:status]
  sleep 0.3
end

我添加了一个短循环来消耗时间。没有它,你不太可能在输出中看到“处理”:

219
processing
fetching
processing
7255
fetching
fetching
fetching
62471
processing
waiting
waiting