Saltar al contenido

¿Cómo limitar el tiempo de ejecución de una llamada a función?

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)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *