Подтвердить что ты не робот

Как тайм-аут функции в python, тайм-аут меньше секунды

Спецификация проблемы:

Я просматриваю действительно большое количество строк файла журнала, и я распределяю эти строки на группы для регулярных выражений (RegExses), которые я сохранил с помощью функции re.match(). К сожалению, некоторые из моих RegExses слишком сложны, и Python иногда получает возможность отступать от ада. Из-за этого мне нужно защитить его каким-то таймаутом.

Проблемы:

  • re.match, я использую функцию Python и, как я узнал где-то здесь, в StackOverflow (мне очень жаль, я не могу найти ссылку сейчас:-(). Очень сложно прерывать поток с запущенной библиотекой Python. По этой причине потоки не работают.
  • Поскольку оценка функции re.match занимает относительно короткое время, и я хочу анализировать с этой функцией большое количество строк, мне нужна некоторая функция тайм-аута, которая не займет слишком много времени (это делает потоки еще менее подходящими, это занимает очень много времени, чтобы инициализировать новый поток), а может быть установлено менее одной секунды.
    По этим причинам ответы здесь - Время ожидания вызова функции и здесь - Функция тайм-аута, если требуется слишком много времени для завершения с помощью декоратора (будильник - 1сек и более), отключен от таблицы.

Сегодня утром я искал решение этого вопроса, но я не нашел удовлетворительного ответа.

4b9b3361

Ответ 1

Решение:

В конце концов, решение не было таким сложным, но я подумал, что может быть полезно для некоторых других безнадежно уложенных парней, таких как я, чтобы опубликовать это простое решение здесь.

Я немного модифицировал script, размещенный здесь: Функция тайм-аута, если требуется слишком много времени для завершения.

И вот код:

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

И тогда вы можете использовать его следующим образом:

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)

Какая печать

Time elapsed: 0.010s

Надеюсь, это кому-то поможет: -)