2011-06-25 61 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