From the way you've defined your problem, I think this is a good situation for using a generator based co-routine. That is, change myFunction to a generator that yields every time it has finished with a step of its processing (e.g. do1 or do2) and run it from a loop that checks the time.
Here's a simple implementation that repeatedly runs a single somework function, but you could easily call different functions, or even do work directly in the myFunction generator:
import time
def somework():
print "Doing some work!"
time.sleep(2)
def myFunction():
try:
print "Started myFunction()"
yield somework()
yield somework()
yield somework()
yield somework()
yield somework()
print "Done with myFunction()"
except GeneratorExit:
print "Exiting myFunction() early!"
def main():
start = time.time()
gen = myFunction()
for _ in gen:
if time.time() > start+5:
gen.close();
There are some benefits to using this structure:
- First off,
myFunction gets to choose where it yields to the outer loop, so it won't get killed at an unexpected time. If it's manipulating some external data structure, you can ensure it always yields with everything in a consistent state.
- Second,
myFunction can yield intermediate values, if that is useful. The example code above yields None (since that's the return value from somework but you can change that easily. The main loop puts the latest yielded value in the _ variable (which is not used), but you can rename that variable and use its value in the timeout block if you want.
- Finally, by catching the
GeneratorExit exception, myFunction can run any cleanup code that it needs before it shuts down.