Generalizing a bit, you want to perform some operation with a time
limit. If the operation finishes before the time limit is reached, all
is well. If not, you want the operation to be interrupted, and execution
to pass on to whatever comes next.
This suggests that we want to set up a try ... except
structure, with
the exception being raised after a certain amount of time has passed.
This question doesn’t specify a platform. I can’t provide code for
Windows. This question and this other question seem useful for
that.
Under Unix, we set up a signal handler function that raises the
exception; tell Python to call that function when the SIGALRM
signal
is received; and set a timer that will send that signal when it times
out. See example code below.
#!/usr/bin/env python2
import signal
from time import sleep # only needed for testing
timelimit_seconds = 3 # Must be an integer
# Custom exception for the timeout
class TimeoutException(Exception):
pass
# Handler function to be called when SIGALRM is received
def sigalrm_handler(signum, frame):
# We get signal!
raise TimeoutException()
# Function that takes too long for bananas and oranges
def mix(f):
if 'n' in f:
sleep(20)
else:
sleep(0.5)
fruits = ['apple', 'banana', 'grape', 'strawberry', 'orange']
for f in fruits:
# Set up signal handler for SIGALRM, saving previous value
old_handler = signal.signal(signal.SIGALRM, sigalrm_handler)
# Start timer
signal.alarm(timelimit_seconds)
try:
mix(f)
print f, 'was mixed'
except TimeoutException:
print f, 'took too long to mix'
finally:
# Turn off timer
signal.alarm(0)
# Restore handler to previous value
signal.signal(signal.SIGALRM, old_handler)