ruby - 确定 ruby 线程状态

标签 ruby multithreading web-scraping

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

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

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

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

正确的做法是什么?

最佳答案

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

关于ruby - 确定 ruby 线程状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12990844/

相关文章:

java - 等待线程永远不会醒来

python - 将网页抓取表放入 Pandas Dataframe 中

java - 更改 PriorityBlockingQueue 中的现有任务优先级

ruby - RSpec 规范伪造类常量的最佳实践或解决方法

ruby-on-rails - ActiveSupport::TestCase 不会运行数据库命令?

ruby - RSpec 有没有办法同时断言调用次数和参数列表?

c# - 以不同的方式启动和完成锁定

python - Request.get超时

python,lxml检索列表中的所有元素

ruby - 如何在 Ruby 中复制散列?