Search code examples
pythonlinuxtimertimeoutscheduling

How to limit the amount of time a function can run for (add a timeout)?


How to set a limit on the maximum amount of time a function can run for? For example, using time.sleep as a placeholder function, how to limit the amount of time time.sleep can run to a maximum of 5 mins (300 seconds)?

import time

try:
    # As noted above `time.sleep` is a placeholder for a function 
    # which takes 10 minutes to complete.
    time.sleep(600)
except:
    print('took too long')

That is, how can time.sleep(600) above be limited and interrupted after 300 seconds?


Solution

  • On POSIX you have a simple and clean solution available in signal module.

    import signal
    import time
    
    class Timeout(Exception):
        pass
    
    def handler(sig, frame):
        raise Timeout
    
    signal.signal(signal.SIGALRM, handler)  # register interest in SIGALRM events
    
    signal.alarm(2)  # timeout in 2 seconds
    try:
        time.sleep(60)
    except Timeout:
        print('took too long')
    

    Caveats:

    • Does not work on all platforms, e.g. Windows.
    • Does not work in threaded applications, only the main thread.

    For other readers where the caveats above are a deal breaker, you will need a more heavyweight approach. The best option is usually to run the code in a separate process (or possibly a thread), and terminate that process if it takes too long. See multiprocessing module for example.