python function execution deadlines - in simple examples
Sometimes a Python method call will take a long time (even
) to return a value. This isn't a good thing -- it can block your server, or take up lots of wasted time on the CPU. Thankfully, it's easy to limit the amount of time that functions can execute for using python's
Here, a function is only allowed to execute for 5 seconds:
import signal def handler(signum, frame): print 'Signal handler called with signal', signum # Set the signal handler and a 5-second alarm signal.signal(signal.SIGALRM, handler) signal.alarm(5) # This function may hang indefinitely takes_a_long_time() signal.alarm(0)
Something nicer using function decorators
It's nice to be able to do this, but we can do better. Copying that same logic into each function we'd like to deadline would be bad design. Thankfully, Using Python's decorator syntax, we can decorate particular methods that we want to give deadlines to as easily as this:
@deadline(5) def f(): pass
Snippets to do this can be found online ( here ) but they use old Python syntax, which might result in the following error:
AttributeError: 'str' object has no attribute 'func_name'
Here is the corrected code that works in more recent versions of python (like 2.7):
class TimedOutExc(Exception): pass def deadline(timeout, *args): def decorate(f): def handler(signum, frame): raise TimedOutExc() def new_f(*args): signal.signal(signal.SIGALRM, handler) signal.alarm(timeout) return f(*args) signal.alarm(0) new_f.__name__ = f.__name__ return new_f return decorate
Now, we can easily "decorate" any function with a deadline. In this case, we'd want to not let the function run for more than 5 seconds:
@deadline(5) def take_a_long_time(): while(True): pass
If you want to catch the exception rather than halting all program execution, just do it like you catch any other exception:
try: take_a_long_time() except TimedOutExc as e: print "took too long"
Be careful when using these kinds of signal-based deadlines in
or multithreaded functions. Read more
if you are having trouble with that.