Timeout On A Python Function Call Inside Timeit
I have a function, let's call it my_function(*args, **kwargs), that depending on the arguments passed to it takes anywhere from 30 seconds to many many hours (days). I have a list
Solution 1:
Based on the answer found in Timeout function using threading in python does not work. If you try it out on foo(x)
it does indeed stop counting unlike the my previous answer.
import multiprocessing as mp
import timeit
def timeout(func, args=(), kwargs=None, TIMEOUT=10, default=None, err=.05):
if hasattr(args, "__iter__") and not isinstance(args, basestring):
args = args
else:
args = [args]
kwargs = {} if kwargs is None else kwargs
pool = mp.Pool(processes = 1)
try:
result = pool.apply_async(func, args=args, kwds=kwargs)
val = result.get(timeout = TIMEOUT * (1 + err))
except mp.TimeoutError:
pool.terminate()
return default
else:
pool.close()
pool.join()
return val
def Timeit(command, setup=''):
return timeit.Timer(command, setup=setup).timeit(1)
def timeit_timeout(command, setup='', TIMEOUT=10, default=None, err=.05):
return timeout(Timeit, args=command, kwargs={'setup':setup},
TIMEOUT=TIMEOUT, default=default, err=err)
Solution 2:
After some more fiddling I have a initial answer based on Timeout function using threading. I would still love to hear from anyone who has better ideas as I am still new to this.
def timeout(func, args=None, kwargs=None, TIMEOUT=10, default=None, err=.05):
if args is None:
args = []
elif hasattr(args, "__iter__") and not isinstance(args, basestring):
args = args
else:
args = [args]
kwargs = {} if kwargs is None else kwargs
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* (1 + err))
if it.isAlive():
return default
else:
return it.result
def timeit_timeout(command, setup='', TIMEOUT=10, default=None, err=.05):
import timeit
f = lambda: timeit.Timer(command, setup=setup).timeit(1)
return timeout(f,TIMEOUT=TIMEOUT, default=default, err=err)
if __name__ == '__main__':
from time import sleep
setup = 'gc.enable()\nfrom time import sleep'
for n in range(1,15):
command = 'sleep({})'.format(n)
print timeit_timeout(command, setup=setup, default=float('Inf'))
Post a Comment for "Timeout On A Python Function Call Inside Timeit"