python 中断命令如果超时
可能重复的问题:
Python函数调用超时
如何在Python中设置函数超时,超时少于一秒
我在一个循环里运行一个函数,像这样:
for element in my_list:
my_function(element)
但由于某些原因,有些元素可能会导致这个函数处理时间非常长(可能甚至会出现我无法追踪的无限循环)。所以我想加一些控制,让它在处理当前元素时,如果超过2秒就跳过它。这样该怎么做呢?
2 个回答
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)
这个函数 troublesome
是不会自己结束的。如果你用 try_one(troublesome,2)
,它会在2秒后成功超时。
2
我不太建议使用最明显的解决办法——也就是用signal.alarm()和一个信号处理器来异步地抛出异常,从而跳出任务执行。理论上这应该很好用,但实际上,cPython解释器的代码并不能保证处理器会在你想要的时间内执行。信号处理可能会因为一些字节码指令的执行而被延迟,所以即使你明确取消了警报(在try块之外),异常仍然可能在超时代码执行完后被抛出。
我们经常遇到的问题是,警报处理器的异常会在超时代码完成后才被抛出。
由于线程控制的选项不多,我通常依赖进程控制来处理需要设置超时的任务。基本上,就是把任务交给一个子进程,如果任务花费的时间太长,就杀掉这个子进程。multiprocessing.pool的功能并没有那么复杂,所以我自己做了一个控制池来实现这种控制。