2011-06-25 58 views
3

我使用Ruby线程像这样需要更长的时间:退出线程,如果不是X秒

threads = [] 

for page in pages 
    threads << Thread.new(page) { |myPage| 

    h = Net::HTTP.new(myPage, 80) 
    puts "Fetching: #{myPage}" 
    resp, data = h.get('/', nil) 
    puts "Got #{myPage}: #{resp.message}" 
    } 
end 

threads.each { |aThread| aThread.join } 

比方说,我想杀死正在一分钟后,仍在运行的所有线程。我将如何做到这一点?

回答

4

我经常超时,我的操作与Timeout

require "timeout" 
Timeout.timeout(seconds) do 
... 
end 

也许this可以帮助,所以你的情况,我觉得这样的事情应该工作:

begin 
    Timeout.timeout(5) do 
    for page in pages 
     threads << Thread.new(page) { |myPage| 

     h = Net::HTTP.new(myPage, 80) 
     puts "Fetching: #{myPage}" 
     resp, data = h.get('/', nil) 
     puts "Got #{myPage}: #{resp.message}" 
     } 
    end 
    threads.each { |aThread| aThread.join } 
    end 
rescue Timeout::Error 
    # kill threads here 
end 

但是你确定你的控制器是做这件事的最佳地点?他们在背景任务中不会更好吗?

+0

什么,我会换这个局面?我想杀死线程,但仍然呈现页面 –

+0

如果时间限制到期,这相当于杀人? – Geo

+0

任何事情都应该在'#kill threads here'处出现? –

3

而不是诉诸线程管理的,我只想的h建成后添加此行:

... 
h = Net::HTTP.new(myPage, 80) 
h.read_timeout = 60 
... 

这样,HTTP请求将在60秒超时,该线程将正常退出。

编辑:当然,您必须检查请求是否成功或超时。 ;)

进一步编辑:让我来扩大你的代码:

threads = [] 

for page in pages 
    threads << Thread.new(page) { |myPage| 
    begin 
     h = Net::HTTP.new(myPage, 80) 
     h.read_timeout = 60 
     puts "Fetching: #{myPage}" 
     resp, data = h.get('/', nil) 
     puts "Got #{myPage}: #{resp.message}" 
     # do something on a successful HTTP request. 
    rescue TimeoutError => tErr 
     # do something on an HTTP request that did timeout. 
    end 
    } 
end 

threads.each { |aThread| aThread.join } 
+0

我真的不想这样做 –

+0

那么,你在线程中耗时的操作实际上就是HTTP请求。那么,为什么不呢? – dimitarvp