2016-04-21 74 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来允许调用者发信号通知工作者函数应该尽早终止。

有些帖子(如上面链接的帖子)建议使用信号,但不幸的是信号可能会导致更多的复杂性,所以不推荐。