python regex function timeout

Cómo el tiempo de espera funciona en Python, tiempo de espera menos de un segundo



regex function (1)

Especificación del problema:

Estoy buscando a través de una gran cantidad de líneas de un archivo de registro y estoy distribuyendo esas líneas a grupos para expresiones regulares (RegExses) que he almacenado usando la función re.match() . Desafortunadamente, algunos de mis RegExses son demasiado complicados y Python a veces retrocede en el infierno. Debido a esto, necesito protegerlo con algún tipo de tiempo de espera.

Problemas:

  • re.match , estoy usando, es la función de Python y, como descubrí en algún lugar aquí en StackOverflow (lo siento mucho, no puedo encontrar el enlace ahora :-() . Es muy difícil interrumpir el hilo ejecutando Python''s biblioteca. Por esta razón los hilos están fuera del juego.
  • Debido a que la evaluación de la función re.match toma relativamente poco tiempo y quiero analizar con esta función una gran cantidad de líneas, necesito una función de tiempo de espera que no demore demasiado en ejecutarse (esto hace que los hilos sean aún menos adecuados, toma mucho tiempo tiempo para inicializar el nuevo hilo) y se puede establecer en menos de un segundo .
    Por esas razones, las respuestas aquí - Tiempo de espera en una llamada de función y aquí - Función de tiempo de espera si se tarda demasiado en terminar con el decorador (alarma - 1 seg y más) están fuera de la mesa.

He pasado esta mañana buscando una solución a esta pregunta, pero no encontré ninguna respuesta satisfactoria.


Solución:

Al final, la solución no fue tan complicada, pero pensé, que podría ser útil para otros tipos apilados sin esperanzas como yo para publicar esta solución simple aquí.

Acabo de publicar una secuencia de comandos modificada: la función de tiempo de espera es demasiado larga para finalizar .

Y aquí está el código:

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

Y luego puedes usarlo así:

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)

Que imprime

Time elapsed: 0.010s

Espero que esto sea de ayuda para alguien :-)