In this article, we will be discussing the func_timeout module in Python. Let’s say a program needs to make a large function call, but it has a limited time period for the function to terminate. A practical way to limit the execution of a function call is to use func_timeout.func_timeout()
from the Python func_timeout module.
About the Module
Python func_timeout module allows us to specify timeouts during existing function calls and stoppable threads. As of Python 3.10, it is NOT part of the Python standard library.
You can install it manually using PIP
.
pip install func_timeout
Use Case Demonstration of Python func_timeout
Let’s refer to the following sample program that implements the module.
import func_timeout
def largeFunction():
while True: pass
return 'PythonPool.com'
def runFunction(f, max_wait, default_value):
try:
return func_timeout.func_timeout(max_wait, largeFunction)
except func_timeout.FunctionTimedOut:
pass
return default_value
x = runFunction(largeFunction, 5, 'Python')
print(x)
Output
Python
Explanation
The function runFunction
makes the call func_timeout.func_timeout(max_wait,largeFunction)
in order to all largeFunction
without arguments nor wait time (max_wait
).
If largeFunction()
fails from stopping within the time interval, an error is thrown and caught by the except block.
As largeFunction()
failed to return a value within the time interval, the default value “Python” is returned.
Python timeout Function After “n” Seconds Using func_timeout
func_timeout
allows us to run the given function for up to “timeout” seconds.
func_timeout(timeout, func, args=(), kwargs=None)
Any exception raised during the call will return func
returns.
timeout
parameter indicates the maximum number of seconds to run func
before exiting.
args
receives a tuple of any ordered arguments to pass to the function.
FunctionTimedOut
exception is thrown upon failure to run within the given time frame.
Finally, the function will return the return value of func
.
Python Function Timeout Multiprocessing
Using the multiprocessing module in Python, we can terminate a function if it breaches a time hold threshold. Refer to the following program.
from multiprocessing import Pool, TimeoutError
import time
def f(x):
return x*x
if __name__ == '__main__':
with Pool(processes=4) as pool:
res = pool.apply_async(f, (20,))
print(res.get(timeout=1))
...
...
...
res = pool.apply_async(time.sleep, (10,))
Creating a Python Loop Delay without time.sleep()
timelimit = 21
while timelimit > 0 :
print "%s seconds remaining" % (timelimit)
timelimit = timelimit -1
We need to iterate the above loop within 20 seconds and once per each second. In this situation, we cannot use time.sleep()
as it will cause the entire application to be unresponsive for a particular amount of time.
import time
max = 31
start = time.time()
while True:
time.sleep(0.1)
print( "looping...")
#Remaining time after each iteration
remaining = max + start - time.time()
print( "%s seconds remaining" % int(remaining))
#After final interation, break the loop
if remaining <= 0:
break
The above implementation uses time.sleep()
in order to prevent numerous print statements in the output console. It has no direct effect on the iterations.
Stopping a Python Function after a Timeout
With the help of the multiprocessing module, we can do exactly that.
import multiprocessing
import time
# Sample Function
def myFunction():
for i in range(100):
print("iteration")
time.sleep(1)
if __name__ == '__main__':
# "Starting" myFunction as a process
p = multiprocessing.Process(target=myFunction)
p.start()
# Waits for 10 seconds or until the function execution is over
p.join(10)
# If the process "p" is still alive
if p.is_alive():
print("end thread")
# The process is terminated
p.terminate()
p.join()
The above program allows the function to run within 10 seconds. If 10 seconds have passed, the process is automatically terminated.
How to Implement a StoppableThread Class in Python
In programming, it is precarious to terminate a thread unexpectedly. A thread may contain a vital resource to the program; closing it without proper care may cause unexpected behavior. Threads may also consist of other sub-threads which need the same attention.
To ensure this, we can implement an exit request flag that checks at regular intervals for the exit. The Python threading
module allows us to implement this. Let’s refer to the following program
import threading
class StoppableThread(threading.Thread):
def __init__(self, *args, **kwargs):
super(StoppableThread, self).__init__(*args, **kwargs)
self._stop_event = threading.Event()
def stop(self):
self._stop_event.set()
def stopped(self):
return self._stop_event.is_set()
StoppableThread
has a method stop()
. As it’s called, it will exit the thread and waits to exit properly using the join()
method. The thread regularly checks the exit flag.
FAQs on Func timeout Python
func_timeout works in Windows systems under the following versions of Python.
2.7, 3.4, 3.5, 3.6, 3.7 and 3.10.
Python func_timeout module works on all Linux and Unix-based Operating Systems under the Python versions of:
2.7, 3.4, 3.5, 3.6, 3.7 and 3.10
Conclusion
In this article, we have reviewed the func_timeout module and how its classes allow us to control the runtime of a program. Other packages such as multiprocessing
allow us to perform similar operations.