Preface
In actual development, we may encounter some scenarios where the execution time of the function needs to be limited. For example, when a function is executed for too long, it may cause program lag, resource usage too high, and even affect the stability of the entire system. Therefore, in some cases, we want to limit the maximum time of function calls to ensure that the program can complete the task within a reasonable time frame, or take other measures in case of timeout.
To achieve this, there are several ways to control the execution time of the function. For example, multithreading or asynchronous programming techniques can be used to monitor the execution of functions within a specified time range. If the function fails to complete execution within a specified time, the function can be interrupted and a timeout prompt or alternate logic can be executed. This method can not only improve the robustness of the program, but also effectively avoid system performance problems caused by the long execution time of a single function.
Limiting the maximum time of function calls is a very practical technical method that can help developers better control the behavior of programs, improve user experience, and ensure the stability and reliability of the system.
func-timeout
func-timeout is a Python library that allows setting timeouts for functions, preventing code from running for a long time or blocking infinitely. It is suitable for scenarios where execution time needs to be enforced, such as network requests, compute-intensive tasks, or code that may have a dead loop.
1. Install func-timeout
You can use pip to install:
pip install func-timeout
2. Basic usage
The most common way is func_timeout, which allows a function to be run within a specified time and an exception is thrown when a timeout is timed.
from func_timeout import func_timeout, FunctionTimedOut import time def long_running_task(): (5) # Simulate long-running tasks return "Task completed" try: result = func_timeout(3, long_running_task) # Set 3 seconds timeout print(result) except FunctionTimedOut: print("Function execution timed out!")
explain:
func_timeout(3, long_running_task): Try running long_running_task in 3 seconds
FunctionTimedOut Exception indicates that the function timeout has not been completed
You can also use the decorator method to set the timeout for the function:
from func_timeout import func_set_timeout import time @func_set_timeout(2) # Limit the running time of this function to 2 secondsdef long_task(): (5) # The task actually takes 5 seconds return "Finished" try: print(long_task()) except FunctionTimedOut: print("Function execution timed out!")
This method is suitable for functions that require multiple calls, avoiding manually setting timeouts for each call.
func-timeout is essentially dependent on multi-threading or multi-processing to implement timeout control, and may not be applicable to the main thread (such as Jupyter Notebook). It also cannot be used for while True dead loops within main thread, because Python's GIL may affect signal processing.
Custom processes
In addition to using the above library, you can also use one process to time and detect timeouts yourself, and another process to call Python functions. The following is the specific implementation code:
import time from itertools import count from multiprocessing import Process def inc_forever(): print('Starting function inc_forever()...') while True: (1) print(next(counter)) def return_zero(): print('Starting function return_zero()...') return 0 if __name__ == '__main__': # counter is an infinite iterator counter = count(0) p1 = Process(target=inc_forever, name='Process_inc_forever') p2 = Process(target=return_zero, name='Process_return_zero') () () (timeout=5) (timeout=5) () () if is None: print(f'Oops, {p1} timeouts!') if == 0: print(f'{p2} is luck and finishes in 5 seconds!')
The operation results are as follows:
Starting function inc_forever()... Starting function return_zero()... 0 1 2 3 4 Oops, <Process(Process_inc_forever, started)> timeouts! <Process(Process_return_zero, stopped)> is luck and finishes in 5 seconds!
From the exit code, it can be seen thatinc_forever()
The function timed out (the exit code isNone
),andreturn_zero()
The function completed successfully in 5 seconds.
Subprocess parameter setting timeout
Starting with Python 3.5,subprocess
The module provides a convenient and recommendedrun()
API, it has built-in timeout support. Here is the sample code:
import subprocess r = (['echo', 'hello timeout'], timeout=5) print( f'''type(r)={type(r)}, ={}, ={}, ={}, ={}''' ) try: r = (['ping', ''], timeout=5) except as e: print(e)
The operation results are as follows:
hello timeout type(r)=<class ''>, =['echo', 'hello timeout'], =0, =None, =None PING (216.58.194.164) 56(84) bytes of data. 64 bytes from ...: icmp_seq=1 ttl=54 time=10.4 ms 64 bytes from ...: icmp_seq=2 ttl=54 time=5.90 ms 64 bytes from ...: icmp_seq=3 ttl=54 time=6.19 ms 64 bytes from ...: icmp_seq=4 ttl=54 time=9.04 ms 64 bytes from ...: icmp_seq=5 ttl=54 time=16.7 ms Command '['ping', '']' timed out after 5 seconds
When timeout, aTimeoutExpired
Exception.
Signals
For UNIX systems, you can also usesignal
Module, throws an exception by sending a signal to the processor after 5 seconds. However, this method is relatively low-level and not intuitive enough.
import signal def handler(signum, frame): raise TimeoutError("Function timeout") def my_function(): pass (, handler) (5) try: my_function() except TimeoutError: print("Function timeout") finally: (0)
Summarize
In development, limiting the execution time of function is an important means to improve program stability and user experience. This article introduces several implementation methods:
func-timeout library:pass
func_timeout
Or decoratorfunc_set_timeout
, can set the timeout time for the function, and an exception will be thrown when the timeout is. Suitable for network request or compute-intensive tasks.Custom processes:Use
multiprocessing
Module creation child process execution function, throughjoin(timeout)
Control timeout and terminate the process after the timeout.subprocess module: Starting from Python 3.5,
()
Supports timeout parameters, timeout will be thrownTimeoutExpired
Exception, suitable for external command calls.Signaling mechanism: In UNIX systems, use
signal
The module sets a timeout signal, and an exception is triggered after the timeout, but the implementation is lower-level.
These methods have their own advantages and disadvantages, and developers can choose appropriate solutions based on actual needs.
The above is the detailed content of four methods for Python to handle function call timeouts. For more information about Python function call timeouts, please follow my other related articles!