Python aborts a command if it takes longer than it should

Possible duplicate:
Python function call timeout
As a python timeout function, time in less than a second

I run a function inside a for loop, for example:

for element in my_list: my_function(element) 

for some reason, some elements may cause the function to take a very long processing time (perhaps even some infinite loop that I cannot trace where it comes from). Therefore, I want to add an outline control to skip the current element if, for example, it takes more than 2 seconds to process it. How can I do that?

+4
source share
2 answers

Something like that:

 import signal import time class Timeout(Exception): pass def try_one(func,t): def timeout_handler(signum, frame): raise Timeout() old_handler = signal.signal(signal.SIGALRM, timeout_handler) signal.alarm(t) # triger alarm in 3 seconds try: t1=time.clock() func() t2=time.clock() except Timeout: print('{} timed out after {} seconds'.format(func.__name__,t)) return None finally: signal.signal(signal.SIGALRM, old_handler) signal.alarm(0) return t2-t1 def troublesome(): while True: pass try_one(troublesome,2) 

The troublsome function troublsome never return on its own. If you use try_one(troublesome,2) , it expires successfully after 2 seconds.

+1
source

I would give up the most obvious answer - using signal.alarm () and an alarm handler that asynchronously throws an exception to jump out of the task. Theoretically, this should work fine, but in practice, the cPython interpreter code does not guarantee that the handler runs within the required time interval. Signal processing can be delayed by x by the number of bytecode instructions, so an exception can still be raised after an explicit rejection of the buffer (outside the context of the try block).

The problem we encountered regularly was that an exception to the alarm handler would be raised after the timecode was completed.

Since there is not much flow control, I relied on process control to handle tasks that need to timeout. Essentially, the bottom line is to pass the task to the child process and kill the child process if the task takes too long. multiprocessing.pool is not quite that complicated - so I have a class consisting of two rows for this level of control.

+1
source

All Articles