Using signals to timeout a function such as in: http://www.pycs.net/users/0000231/weblog/2004/10/ http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/307871 won't work if the function you are calling overrides the alarm. Using threads gives you away around this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | def timeout(func, args=(), kwargs={}, timeout_duration=1, default=None):
import threading
class InterruptableThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.result = None
def run(self):
try:
self.result = func(*args, **kwargs)
except:
self.result = default
it = InterruptableThread()
it.start()
it.join(timeout_duration)
if it.isAlive():
return default
else:
return it.result
|
Apparently cx_Oracle overrides the alarm signal so the signal handling method of timingout a function wasn't working for me. I came up with the threading method as a way around this.
An improved version supporting exceptions and decorators. Check out http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/483752
Why this doesn't work (!?):
def test(): while True: print "Test" time.sleep(1.5)
if __name__ == '__main__': timeout(test, timeout_duration=3)
Nice, but how do you kill the thread after the timeout?