Python: Gestión de excepciones de tiempo de espera con Signal.Alarm

Estoy intentando implementar un controlador de excepciones de tiempo de espera si una llamada de función está demorando demasiado.

EDITAR : De hecho, estoy escribiendo un script de Python usando subproceso, que llama a un progtwig antiguo de C ++ con argumentos. Sé que el progtwig se cuelga de vez en cuando, sin devolver nada. Es por eso que estoy tratando de poner un límite de tiempo y pasar a la siguiente llamada con diferentes argumentos y etc.

He estado buscando y tratando de implementarlo, pero no funciona bien, así que deseo obtener ayuda. Lo que tengo hasta ahora es:

#! /usr/bin/env python import signal class TimeOutException(Exception): def __init__(self, message, errors): super(TimeOutException, self).__init__(message) self.errors = errors def signal_handler(signum, frame): raise TimeOutException("Timeout!") signal.signal(signal.SIGALRM, signal_handler) signal.alarm(3) try: while True: pass except TimeOutException: print "Timed out!" signal.alarm(0) 

EDIT : El mensaje de error que recibo actualmente es “TypeError: init () toma exactamente 3 argumentos (2 dados)

Además, me gustaría hacer una pregunta básica con respecto al bloque de excepción. ¿cuál es la diferencia de rol entre el código justo debajo de “excepto la excepción TimeOutException” y el código en el “controlador de excepciones”? Parece que ambos pueden hacer lo mismo?

Cualquier ayuda sería apreciada.

Si una llamada de función está tomando demasiado tiempo

Me doy cuenta de que esto podría no ser obvio para los desarrolladores sin experiencia, pero los métodos aplicables para abordar este problema dependen completamente de lo que esté haciendo en esta “función ocupada”, como:

  • ¿Es este un cálculo pesado? En caso afirmativo, ¿qué intérprete de Python está utilizando? ¿CPython o PyPy? Si CPython: ¿este cálculo solo utiliza el bytecode de Python o implica llamadas a funciones subcontratadas al código de máquina comstackdo (que puede contener el locking de intérprete global de Python durante un período de tiempo incontrolable)?

  • ¿Es esto mucho trabajo de E / S? En caso afirmativo, ¿puede abortar este trabajo de E / S en un estado arbitrario? ¿O necesitas limpiar adecuadamente? ¿Está utilizando un determinado marco como gevent o Twisted?

Edición: Entonces, parece que estás generando un subproceso y esperas a que termine. Genial, ese es uno de los problemas más simples para implementar un control de tiempo de espera. Python (3) envía una característica correspondiente! 🙂 Mira esto

https://docs.python.org/3/library/subprocess.html#subprocess.call

El argumento de tiempo de espera se pasa a Popen.wait (). Si el tiempo de espera expira, el proceso hijo se eliminará y luego se esperará de nuevo. La excepción TimeoutExpired se volverá a elevar después de que el proceso secundario haya finalizado.

Edit2:

Código de ejemplo para usted, guárdelo en un archivo y ejecútelo con Python 3.3, al menos:

 import subprocess try: subprocess.call(['python', '-c', 'print("hello")'], timeout=2) except subprocess.TimeoutExpired as e: print("%s was terminated as of timeout. Its output was:\n%s" % (e.cmd, e.output)) try: subprocess.call(['python'], timeout=2) except subprocess.TimeoutExpired as e: print("%s was terminated as of timeout. Its output was:\n%s" % (e.cmd, e.output)) 

En el primer caso, el subproceso vuelve inmediatamente. No se generará ninguna excepción de tiempo de espera. En el segundo caso, el tiempo de espera expira, y su proceso de control (el proceso que se ejecuta arriba del script) intentará terminar el subproceso. Esto tiene éxito. Después de eso, el subprocess.TimeoutExpired se genera y el controlador de excepciones se ocupa de ello. Para mí, la salida del script anterior es ['python'] was terminated as of timeout. Its output was: None ['python'] was terminated as of timeout. Its output was: None :