2016-04-21 76 views
2

我有一個python代碼花費的時間太長,如果它需要超過幾秒鐘的時間,我想停止並跳過此函數的執行。如果函數耗時過長,跳過循環?

對於如: -

功能我想時間是

batch_xs, batch_ys = train_loadbatch_from_lists(batch_size) 

在某些情況下,這種函數調用花費的時間太長,想取消它。

我參考尋找這樣的事情

if time for batch_xs, batch_ys = train_loadbatch_from_lists(batch_size) > 20 seconds: 
    then skip 

this post

我想知道如何在發生超時時再次調用該函數。

對於如: -

@timeout(15) 
def abcd(hello): 
#some def 

我想再次調用該函數如果它與計時器。

+2

這裏有一些想法:http://stackoverflow.com/questions/2281850/timeout-function-if-it-takes-too-long-to-finish – Miikka

+0

是的,我經歷了它。但我不確定我知道如何使用它。 所以,如果我有一個函數定義之前定義的@timeout(15),並且如果發生錯誤,我想再次調用它。你知道如何做到這一點嗎? –

+0

我真的不會推薦使用信號。他們看起來像一個體面的解決方案,但有各種奇怪的副作用,角落案件等,並可能導致更多的問題比他們解決。 – gavinb

回答

1

當你在同一個線程中調用一個函數時,它通常不會返回,直到完成。你打電話的功能必須首先被設計爲可中斷的。有很多方法可以達到這個目的,但具有不同程度的複雜性和通用性。

也許最簡單的方法是將時間限制傳遞給你的函數,並以小塊處理工作。處理完每個塊後,檢查經過的時間是否超過超時時間,如果超過,請提早提前退出。

下面的例子說明了這個想法,對工作採取每塊的一個隨機時間,其有時會完全有時超時:

import time 
import random 
import datetime 

class TimeoutException(Exception): 
    def __init__(self, *args, **kwargs): 
     Exception.__init__(self, *args, **kwargs) 

def busy_work(): 

    # Pretend to do something useful 
    time.sleep(random.uniform(0.3, 0.6)) 

def train_loadbatch_from_lists(batch_size, timeout_sec): 

    time_start = datetime.datetime.now() 
    batch_xs = [] 
    batch_ys = [] 

    for i in range(0, batch_size+1): 
     busy_work() 
     batch_xs.append(i) 
     batch_ys.append(i) 

     time_elapsed = datetime.datetime.now() - time_start 
     print 'Elapsed:', time_elapsed 
     if time_elapsed > timeout_sec: 
      raise TimeoutException() 

    return batch_xs, batch_ys 

def main(): 

    timeout_sec = datetime.timedelta(seconds=5) 
    batch_size = 10 
    try: 
     print 'Processing batch' 
     batch_xs, batch_ys = train_loadbatch_from_lists(batch_size, timeout_sec) 
     print 'Completed successfully' 
     print batch_xs, batch_ys 
    except TimeoutException, e: 
     print 'Timeout after processing N records' 

if __name__ == '__main__': 
    main() 

另一種方式來實現,這是運行輔助功能一個單獨的線程,並且使用一個Event來允許調用者發信號通知工作者函數應該儘早終止。

有些帖子(如上面鏈接的帖子)建議使用信號,但不幸的是信號可能會導致更多的複雜性,所以不推薦。