Python, Timeout of Try, Except Statement after X number of seconds?
I've been searching on this but can't seem to find an exact answer (most get into more complicated things like multithreading, etc), I just want to do something like a Try, Except statement where if t开发者_Go百科he process doesn't finish within X number of seconds it will throw an exception.
EDIT: The reason for this is that I am using a website testing software (selenium) with a configuration that sometimes causes it to hang. It doesn't throw an error, doesn't timeout or do anything so I have no way of catching it. I am wondering what the best way is to determine that this has occured so I can move on in my application, so I was thinking if I could do something like, "if this hasn't finished by X seconds... move on".
You can't do it without some sort of multithreading or multiprocessing, even if that's hidden under some layers of abstraction, unless that "process" you're running is specifically designed for asynchronicity and calls-back to a known function once in a while.
If you describe what that process actually is, it will be easier to provide real solutions. I don't think that you appreciate the power of Python where it comes to implementations that are succinct while being complete. This may take just a few lines of code to implement, even if using multithreading/multiprocessing.
A generic solution if you are using UNIX:
import time as time
import signal
#Close session
def handler(signum, frame):
print 1
raise Exception('Action took too much time')
signal.signal(signal.SIGALRM, handler)
signal.alarm(3) #Set the parameter to the amount of seconds you want to wait
try:
#RUN CODE HERE
for i in range(0,5):
time.sleep(1)
except:
print 2
signal.alarm(10) #Resets the alarm to 10 new seconds
signal.alarm(0) #Disables the alarm
The answer (and the question) isn't specific to the try/except statement. If you want to have an infinite loop that isn't infinite (but stops after a while), it probably shouldn't be infinite. For example, change it to use:
while time <= some_value:
Or add an extra check to the body of the loop, making it break when you want it to stop:
while True:
...
if time > some_value:
break
If that isn't possible (for example, because you don't control the loop at all), things get significantly harder. On many systems you could use signal.alarm
to have a signal delivered after a period of time, and then have a signal handler for signal.SIGALRM
that raises your TimeoutError
exception. That may or may not work depending on what the infinite loop actually does; if it blocks signals, or catches and ignores exceptions, or in any other way interferes with the signal handler, that won't work. Another possibility would be to not do the loop in the current process, but in a separate one; you can then terminate the separate process at your whim. It won't be easy to do anything but terminate it, though, so cleanup or recovery of partial work is very hard. (Threads aren't going to work at all, because there's no way to interrupt the separate thread doing the infinite loop.)
精彩评论