python如果需要的时间超过它应该中断一个命令

时间:2013-02-01 17:42:58

标签: python

  

可能重复:
  Timeout on a Python function call
  How to timeout function in python, timout less than a second

我在for循环中运行一个函数,如下所示:

for element in my_list:
    my_function(element)

由于某种原因,某些元素可能导致函数进入非常长的处理时间(甚至可能是一些我无法真正追踪其来源的无限循环)。所以我想添加一些循环控制来跳过当前元素,如果它的处理例如需要超过2秒。怎么办呢?

2 个答案:

答案 0 :(得分:1)

这样的事情:

import signal
import time

class Timeout(Exception): 
    pass 

def try_one(func,t):
    def timeout_handler(signum, frame):
        raise Timeout()

    old_handler = signal.signal(signal.SIGALRM, timeout_handler) 
    signal.alarm(t) # triger alarm in 3 seconds

    try: 
        t1=time.clock()
        func()
        t2=time.clock()

    except Timeout:
        print('{} timed out after {} seconds'.format(func.__name__,t))
        return None
    finally:
        signal.signal(signal.SIGALRM, old_handler) 

    signal.alarm(0)
    return t2-t1

def troublesome():
    while True:
        pass

try_one(troublesome,2)

函数troublsome永远不会自行返回。如果你使用try_one(troublesome,2),它会在2秒后成功超时。

答案 1 :(得分:1)

我会劝阻最明显的答案 - 使用signal.alarm()和一个异步引发异常以跳出任务执行的警报信号处理程序。理论上它应该很好用,但实际上cPython解释器代码并不能保证处理程序在你想要的时间范围内执行。信号处理可以延迟x个字节码指令,因此在您明确取消警报后(在try块的上下文之外)仍然可以引发异常。

我们经常遇到的一个问题是,在超时代码完成后,警报处理程序的异常会被提升

由于通过线程控制没有太多可用,我依靠过程控制来处理必须经历超时的任务。基本上,要点是将任务交给子进程并在任务耗时太长时终止子进程。 multiprocessing.pool并不是那么复杂 - 所以我有一个家庭滚动池来控制这个级别。