Backend Development 8 min read

Enforcing Python Function Timeouts: Libraries, Multiprocessing & Subprocess

This article explains why limiting a function's execution time is crucial for stability, and demonstrates multiple Python techniques—including the func-timeout library, custom multiprocessing, subprocess.run, and signal handling—to set and manage timeouts effectively.

Code Mala Tang
Code Mala Tang
Code Mala Tang
Enforcing Python Function Timeouts: Libraries, Multiprocessing & Subprocess

In real‑world development, long‑running functions can cause freezes, high resource usage, and overall system instability, so limiting a function's maximum execution time is often necessary.

The func-timeout library provides a simple way to set a timeout for any Python function, useful for network requests, compute‑intensive tasks, or code that may enter an infinite loop.

func-timeout

Install the library with:

<code>pip install func-timeout</code>

1. Basic usage

The most common entry point is func_timeout , which runs a function for a given number of seconds and raises an exception on timeout.

<code>from func_timeout import func_timeout, FunctionTimedOut
import time

def long_running_task():
    time.sleep(5)  # simulate a long task
    return "Task completed"

try:
    result = func_timeout(3, long_running_task)  # 3‑second timeout
    print(result)
except FunctionTimedOut:
    print("Function execution timed out!")
</code>

Explanation:

func_timeout(3, long_running_task) attempts to run long_running_task within 3 seconds.

FunctionTimedOut indicates the function did not finish in time.

You can also use the decorator func_set_timeout to apply a timeout to a function definition:

<code>from func_timeout import func_set_timeout
import time

@func_set_timeout(2)  # limit to 2 seconds
def long_task():
    time.sleep(5)
    return "Finished"

try:
    print(long_task())
except FunctionTimedOut:
    print("Function execution timed out!")
</code>

This approach is convenient when the same function is called repeatedly.

Custom multiprocessing solution

Alternatively, you can create a separate process to run the target function and use join(timeout) to enforce a limit.

<code>import time
from itertools import count
from multiprocessing import Process

def inc_forever():
    print('Starting function inc_forever()...')
    while True:
        time.sleep(1)
        print(next(counter))

def return_zero():
    print('Starting function return_zero()...')
    return 0

if __name__ == '__main__':
    counter = count(0)
    p1 = Process(target=inc_forever, name='Process_inc_forever')
    p2 = Process(target=return_zero, name='Process_return_zero')
    p1.start()
    p2.start()
    p1.join(timeout=5)
    p2.join(timeout=5)
    p1.terminate()
    p2.terminate()
    if p1.exitcode is None:
        print(f'Oops, {p1} timeouts!')
    if p2.exitcode == 0:
        print(f'{p2} is luck and finishes in 5 seconds!')
</code>

Running this script produces output showing that inc_forever() timed out while return_zero() completed successfully.

subprocess timeout parameter

Since Python 3.5, subprocess.run() includes a built‑in timeout argument.

<code>import subprocess
r = subprocess.run(['echo', 'hello timeout'], timeout=5)
print(r)

try:
    r = subprocess.run(['ping', 'www.google.com'], timeout=5)
except subprocess.TimeoutExpired as e:
    print(e)
</code>

If the timeout expires, a TimeoutExpired exception is raised.

Signal‑based timeout (UNIX only)

On UNIX systems you can use the signal module to schedule an alarm that raises an exception after a given number of seconds.

<code>import signal

def handler(signum, frame):
    raise TimeoutError("Function timed out")

def my_function():
    pass

signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
try:
    my_function()
except TimeoutError:
    print("函数超时")
finally:
    signal.alarm(0)
</code>

Summary

Limiting function execution time improves program stability and user experience. The main approaches are:

func-timeout library : use func_timeout or the func_set_timeout decorator to raise an exception on timeout.

Custom multiprocessing : spawn a child process and control it with join(timeout) , terminating if it exceeds the limit.

subprocess module : subprocess.run() supports a timeout argument, raising TimeoutExpired on failure.

Signal mechanism : on UNIX, signal.alarm can trigger a timeout exception, though it is lower‑level.

Choose the method that best fits your specific requirements.

PythonError Handlingsignalmultiprocessingsubprocessfunction timeout
Code Mala Tang
Written by

Code Mala Tang

Read source code together, write articles together, and enjoy spicy hot pot together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.