如何在python中超时函数,超时不到一秒

Jen*_*das 20 python regex timeout function

问题规格:

我正在搜索日志文件的大量行,并且我将这些行分发到组以便使用该re.match()函数存储的正则表达式(RegExses).不幸的是,我的一些RegExses太复杂了,Python有时会让自己回归地狱.因此,我需要通过某种超时来保护它.

问题:

  • re.match我正在使用,是Python的功能,正如我在StackOverflow上找到的那样(我真的很抱歉,我现在找不到链接:-().用运行Python的库来中断线程非常困难.这个原因线程已经脱离游戏.
  • 因为re.match函数的评估花费的时间相对较短,而且我想用这个函数分析大量的行,我需要一些不需要太长时间才能执行的超时函数(这使得线程更不合适,需要很长时间才能初始化新线程)并且可以设置为小于一秒.
    由于这些原因,这里的答案 - 函数调用超时 和此处 - 超时功能,如果花费太长时间完成装饰器(警报 - 1秒和更长时间)不在桌面上.

我今天早上都在寻找这个问题的解决方案,但我没有找到任何满意的答案.

Jen*_*das 36

解:

最后,解决方案并不复杂,但我想,对于像我这样的其他绝望堆积的人来说,在这里发布这个简单的解决方案可能会有用.

我只是在这里发布了一些修改过的脚本:超时功能,如果它需要很长时间才能完成.

以下是代码:

from functools import wraps
import errno
import os
import signal

class TimeoutError(Exception):
    pass

def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
    def decorator(func):
        def _handle_timeout(signum, frame):
            raise TimeoutError(error_message)

        def wrapper(*args, **kwargs):
            signal.signal(signal.SIGALRM, _handle_timeout)
            signal.setitimer(signal.ITIMER_REAL,seconds) #used timer instead of alarm
            try:
                result = func(*args, **kwargs)
            finally:
                signal.alarm(0)
            return result
        return wraps(func)(wrapper)
    return decorator
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

from timeout import timeout 
from time import time

@timeout(0.01)
def loop():
    while True:
       pass
try:
    begin = time.time()
    loop()
except TimeoutError, e:
    print "Time elapsed: {:.3f}s".format(time.time() - begin)
Run Code Online (Sandbox Code Playgroud)

哪个打印

Time elapsed: 0.010s
Run Code Online (Sandbox Code Playgroud)

我希望,这对某人有用:-)

  • 是的,但使用setitimer而不是报警解决了问题 - 我现在可以设置浮动的时间 - 我认为当我用完整的语法发布它时会更清楚,我参考了那个答案.我并不是故意偷人的功劳.:-) (5认同)
  • 这基本上是另一个答案的批发副本,唯一的区别是您显示的 seconds 参数可以是浮点数。 (2认同)
  • 由于您使用的是“signal”,因此该代码仅适用于 UNIX...Windows 呢? (2认同)