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

python interrupt a command if it takes longer than it should

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Timeout on a Python function call
How to timeout function in python, timout less than a second

我正在for循环中运行函数,例如:

1
2
for element in my_list:
    my_function(element)

出于某种原因,某些元素可能会导致函数进入非常长的处理时间(甚至可能是一些我无法真正跟踪其来源的无限循环)。因此,我想添加一些循环控件来跳过当前元素,例如,如果它的处理时间超过2秒。怎么能做到?


我不鼓励最明显的回答——使用signal.alarm()和一个异步引发异常以跳出任务执行的报警信号处理程序。理论上讲,它应该工作得很好,但是在实践中,cpython解释器代码不能保证处理程序在您想要的时间范围内执行。信号处理可以被x个字节码指令延迟,因此在显式取消警报后(在try块的上下文之外),仍然可能引发异常。

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

由于线程控制没有太多的可用性,所以我依赖进程控制来处理必须超时的任务。基本上,要点是把任务交给子进程,如果任务花费太长时间,就杀死子进程。multiprocessing.pool并不是那么复杂,所以我有一个用于这种控制级别的本地滚动池。


像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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秒后成功超时。