From: pacopyc on 18 May 2010 05:45 Hi, I've a question for you. I'd like to call a function and waiting its return value for a time max (30 sec). The function could not respond and then I must avoid to wait for infinite time. OS is Windows XP. Can you help me? Thank
From: Albert Hopkins on 18 May 2010 06:24 On Tue, 2010-05-18 at 02:45 -0700, pacopyc wrote: > Hi, I've a question for you. I'd like to call a function and waiting > its return value for a time max (30 sec). > The function could not respond and then I must avoid to wait for > infinite time. OS is Windows XP. > Can you help me? > > Thank This is how I do it with a function decorator. I probably borrowed this from someone and not attributed it. Anyway, it works on Linux, not sure about Windows: def function_timeout(seconds): """Function decorator to raise a timeout on a function call""" import signal class FunctionTimeOut(Exception): pass def decorate(f): def timeout(signum, frame): raise FunctionTimeOut() def funct(*args, **kwargs): old = signal.signal(signal.SIGALRM, timeout) signal.alarm(seconds) try: result = f(*args, **kwargs) finally: signal.signal(signal.SIGALRM, old) signal.alarm(0) return result return funct return decorate
From: Bryan on 18 May 2010 09:22 pacopyc wrote: > I'd like to call a function and waiting > its return value for a time max (30 sec). > The function could not respond and then I must avoid to wait for > infinite time. OS is Windows XP. You can do that using the multiprocessing module, which is in the standard library of Python 2.6 or better. It has certain limitations, but works on XP. The functions have to be defined at module scope, and the arguments and return value must be pickleable. The way multiprocessing works on Windows, it launches a new process which runs the Python interpreter on the module again, and pickles the arguments to pipe them to the new process. Below is a simple working demo/test. The demo uses a timeout of 1 second, rather than the specified 30, to avoid excessive boringness. In practice, timeout_function() would be recklessly inefficient for controlling quick operations; it creates a new pool of processes for each function call that it might need to time-out. That's fixable, but the question here is about a 30-second-plus processing problem, and in that kind of case the overhead of creating one or a few new processes is lost in the noise. -Bryan Olson #-------------------- from multiprocessing import Pool, TimeoutError def timeout_function(timeout, f, args=(), kwargs={}): """ Return f(*args, **kwargs), or if that takes to long raise multiprocessing.TimeoutError. """ pool = Pool(1) return pool.apply_async(f, args, kwargs).get(timeout) #-------------- # simple demo-test: from random import random as rand from time import sleep def sillyfunc(sleeptime): # Time-absorbing function for testing sleep(sleeptime) return 'Done.' if __name__ == '__main__': timeout = 1.0 print "Timeout is %f seconds" % timeout trials = 100 ntimeouts = 0 for _ in range(trials): # time-out probability a bit over 0.5 sleeptime = rand() * timeout * 2 try: result = timeout_function( timeout, sillyfunc, (sleeptime,)) assert result == 'Done.' print 'Ran without timing out' except TimeoutError: ntimeouts += 1 print 'Timed out' if sleeptime < timeout: print '...Sucks! Slept %f' % sleeptime print 'Timed out %d out of %d' % (ntimeouts, trials)
From: Terry Reedy on 18 May 2010 12:22 On 5/18/2010 6:24 AM, Albert Hopkins wrote: > On Tue, 2010-05-18 at 02:45 -0700, pacopyc wrote: >> Hi, I've a question for you. I'd like to call a function and waiting >> its return value for a time max (30 sec). >> The function could not respond and then I must avoid to wait for >> infinite time. OS is Windows XP. >> Can you help me? >> >> Thank > > This is how I do it with a function decorator. I probably borrowed this > from someone and not attributed it. Anyway, it works on Linux, not sure > about Windows: > > def function_timeout(seconds): > """Function decorator to raise a timeout on a function call""" > import signal > class FunctionTimeOut(Exception): > pass > > def decorate(f): > def timeout(signum, frame): > raise FunctionTimeOut() > > def funct(*args, **kwargs): > old = signal.signal(signal.SIGALRM, timeout) > signal.alarm(seconds) from help(signal): alarm() -- cause SIGALRM after a specified time [Unix only] I do not know of any replacement in the stdlib, but one could check the code for multiprocessing to see how it does a timeout. Or check the pywin32 library http://pypi.python.org/pypi/pywin32/210 > try: > result = f(*args, **kwargs) > finally: > signal.signal(signal.SIGALRM, old) > signal.alarm(0) > return result > > return funct > > return decorate > >
|
Pages: 1 Prev: pickle unable to load collection Next: subprocess and gvfs-mount |