Solución:
Una mejora en la respuesta de @ rik.the.vik sería utilizar el with
declaración para darle a la función de tiempo de espera algo de azúcar sintáctico:
import signal
from contextlib import contextmanager
class TimeoutException(Exception): pass
@contextmanager
def time_limit(seconds):
def signal_handler(signum, frame):
raise TimeoutException("Timed out!")
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(seconds)
try:
yield
finally:
signal.alarm(0)
try:
with time_limit(10):
long_function_call()
except TimeoutException as e:
print("Timed out!")
No estoy seguro de cuán multiplataforma podría ser esto, pero el uso de señales y alarmas podría ser una buena forma de ver esto. Con un poco de trabajo, podría hacer esto completamente genérico y utilizable en cualquier situación.
http://docs.python.org/library/signal.html
Entonces, su código se verá así.
import signal
def signal_handler(signum, frame):
raise Exception("Timed out!")
signal.signal(signal.SIGALRM, signal_handler)
signal.alarm(10) # Ten seconds
try:
long_function_call()
except Exception, msg:
print "Timed out!"
Aquí hay una forma de Linux / OSX de limitar el tiempo de ejecución de una función. Esto es en caso de que no desee utilizar subprocesos y desee que su programa espere hasta que finalice la función o expire el límite de tiempo.
from multiprocessing import Process
from time import sleep
def f(time):
sleep(time)
def run_with_limited_time(func, args, kwargs, time):
"""Runs a function with time limit
:param func: The function to run
:param args: The functions args, given as tuple
:param kwargs: The functions keywords, given as dict
:param time: The time limit in seconds
:return: True if the function ended successfully. False if it was terminated.
"""
p = Process(target=func, args=args, kwargs=kwargs)
p.start()
p.join(time)
if p.is_alive():
p.terminate()
return False
return True
if __name__ == '__main__':
print run_with_limited_time(f, (1.5, ), {}, 2.5) # True
print run_with_limited_time(f, (3.5, ), {}, 2.5) # False
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)