Python Timer module

Learn python timer module with practical examples, diagrams, and best practices. Covers python, timer development techniques with visual explanations.

Mastering Python Timers: Schedule and Execute Functions with Precision

Hero image for Python Timer module

Explore various Python timer mechanisms, from simple time.sleep() to advanced threading timers, and learn how to schedule function execution effectively.

In Python, managing time-based operations is a common requirement for many applications, from simple delays to complex scheduled tasks. Whether you need to pause execution, run a function after a specific interval, or repeatedly execute a task, Python offers several tools to achieve this. This article delves into the core concepts and practical implementations of Python timers, helping you choose the right approach for your specific needs.

Basic Timing with time.sleep()

The simplest way to introduce a delay in Python is by using the time.sleep() function. This function pauses the execution of the current thread for a specified number of seconds. While straightforward, it's important to understand that time.sleep() is a blocking call, meaning your program will halt completely during the sleep duration. It's best suited for short, non-critical delays where blocking the main thread is acceptable.

import time

def simple_delay_example():
    print("Starting a 3-second delay...")
    time.sleep(3) # Pause execution for 3 seconds
    print("Delay finished!")

simple_delay_example()

Using time.sleep() for a basic blocking delay.

Non-Blocking Timers with threading.Timer

For scenarios where you need to execute a function after a delay without blocking the main program flow, Python's threading.Timer class is the ideal solution. Timer is a subclass of threading.Thread that executes a function after a specified interval. This allows your main program to continue its execution while the timer runs in a separate thread, making it suitable for background tasks or scheduled events.

import threading
import time

def delayed_function():
    print(f"[{time.time():.2f}] Delayed function executed!")

print(f"[{time.time():.2f}] Program started.")

# Create a Timer that will run delayed_function after 5 seconds
timer = threading.Timer(5, delayed_function)

# Start the timer
timer.start()

print(f"[{time.time():.2f}] Timer started, main program continues...")

# The main program can do other work here
time.sleep(2) # Simulate other work
print(f"[{time.time():.2f}] Main program still running...")

# You can also cancel a timer before it executes
# timer.cancel()
# print("Timer cancelled!")

Implementing a non-blocking timer using threading.Timer.

sequenceDiagram
    participant MainThread
    participant TimerThread

    MainThread->>MainThread: Program Start
    MainThread->>TimerThread: Create Timer(delay, func)
    MainThread->>TimerThread: timer.start()
    Note over MainThread: Main program continues execution
    TimerThread->>TimerThread: Wait for 'delay' seconds
    MainThread->>MainThread: Perform other tasks
    TimerThread-->>TimerThread: Delay elapses
    TimerThread->>TimerThread: Execute 'func()'
    Note over TimerThread: Function runs in separate thread
    MainThread->>MainThread: Program End (or continues)

Sequence diagram illustrating the non-blocking nature of threading.Timer.

Repeated Execution with Timers

While threading.Timer executes only once, you often need to run a function repeatedly at fixed intervals. Python doesn't have a built-in 'repeating timer' class, but you can easily implement one by having the timed function reschedule itself. This pattern is common for tasks like polling, logging, or periodic updates.

import threading
import time

class RepeatingTimer:
    def __init__(self, interval, function, *args, **kwargs):
        self._timer = None
        self.interval = interval
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.is_running = False

    def _run(self):
        self.is_running = False
        self.start()
        self.function(*self.args, **self.kwargs)

    def start(self):
        if not self.is_running:
            self._timer = threading.Timer(self.interval, self._run)
            self._timer.start()
            self.is_running = True

    def stop(self):
        self._timer.cancel()
        self.is_running = False

def periodic_task():
    print(f"[{time.time():.2f}] Performing periodic task...")

# Create a repeating timer that runs every 2 seconds
my_repeating_timer = RepeatingTimer(2, periodic_task)

print("Starting repeating timer...")
my_repeating_timer.start()

# Let it run for a while
time.sleep(7)

print("Stopping repeating timer...")
my_repeating_timer.stop()
print("Program finished.")

Custom RepeatingTimer class for periodic function execution.