πΆ Python Signal Handling β Graceful Shutdown with SIGINT, SIGTERM
π§² Introduction β Why Handle Signals in Python?
Signals are a core part of Unix-based systems. They allow the OS or other processes to notify your program about events such as:
- Ctrl+C (interrupt via SIGINT)
- Termination (SIGTERM)
- Hang-up (SIGHUP)
- Child process events (SIGCHLD)
With Pythonβs built-in signal module, you can intercept and handle these events to:
- Shutdown cleanly
- Save state before exit
- Restart services automatically
- Handle timeouts or inter-process communication
π― In this guide, youβll learn:
- What signals are and how they work in Python
- How to catch signals like SIGINTandSIGTERM
- How to safely clean up resources using signal handlers
- Best practices and limitations of signal handling
β What Is a Signal?
A signal is a software interrupt sent to a process to notify it of an event (e.g., kill signal, interrupt signal).
In Python, you can register handlers that are executed when a signal is received.
π§ Setting Up a Signal Handler
β Basic Signal Handler Example
import signal
import sys
def handle_sigint(signum, frame):
    print("Caught SIGINT (Ctrl+C). Exiting gracefully...")
    sys.exit(0)
signal.signal(signal.SIGINT, handle_sigint)
while True:
    pass  # Keep running
β Pressing Ctrl+C will now trigger the handler and exit cleanly.
π¦ Supported Signals (Common)
| Signal | Meaning | 
|---|---|
| SIGINT | Interrupt from keyboard (Ctrl+C) | 
| SIGTERM | Terminate program (graceful shutdown) | 
| SIGHUP | Hang-up (e.g., terminal closed) | 
| SIGCHLD | Child process status changed | 
| SIGALRM | Alarm signal | 
| SIGUSR1/2 | Custom user-defined signals | 
π§ͺ Example β Handle SIGTERM
def handle_sigterm(signum, frame):
    print("Caught SIGTERM. Cleaning up...")
    sys.exit(0)
signal.signal(signal.SIGTERM, handle_sigterm)
β Useful in Docker containers, daemonized apps, or system services.
π§ Signal Parameters
The signal handler always accepts two arguments:
def handler(signum, frame):
    print(f"Signal received: {signum}")
- signum: signal number (e.g.,- 2for SIGINT)
- frame: current stack frame (useful for debugging)
π οΈ Using signal.SIGALRM for Timeouts
import time
def timeout_handler(signum, frame):
    raise TimeoutError("Operation timed out!")
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(3)  # Set a 3-second timer
try:
    time.sleep(5)  # This will be interrupted
except TimeoutError as e:
    print(e)
β Raises a TimeoutError after 3 seconds.
π΅ Limitations of Signal Handling in Python
| Limitation | Details | 
|---|---|
| Works only in main thread | Handlers won’t run in background threads | 
| Can’t catch SIGKILL,SIGSTOP | These signals are uncatchable | 
| Handlers must be fast | Avoid blocking or long-running logic | 
π§° Real-World Use Case β Graceful Shutdown
import time
running = True
def handle_exit(signum, frame):
    global running
    print("Shutdown signal received.")
    running = False
signal.signal(signal.SIGINT, handle_exit)
signal.signal(signal.SIGTERM, handle_exit)
print("Running... Press Ctrl+C to stop.")
while running:
    time.sleep(1)
print("Clean exit complete.")
π‘ Ideal for cleanup scripts, cron jobs, long-running services.
π Best Practices
| β Do This | β Avoid This | 
|---|---|
| Register signals early in the program | Delaying signal setup after startup | 
| Handle SIGINTandSIGTERMtogether | Ignoring SIGTERMin production apps | 
| Use flags (not direct exits) for long loops | Exiting mid-process in multithreaded apps | 
| Keep handlers lightweight | Running heavy logic or blocking operations | 
π Summary β Recap & Next Steps
Python signal handling allows you to gracefully manage external interrupts and control how your application shuts down or responds to external events.
π Key Takeaways:
- β
 Use signal.signal()to register signal handlers
- β
 Handle SIGINT,SIGTERM, andSIGHUPfor clean shutdowns
- β Signals only affect the main thread
- β
 Use signal.alarm()to implement timeouts
βοΈ Real-World Relevance:
Used in system daemons, CLI tools, Docker containers, and supervised services like Gunicorn, Celery, or custom schedulers.
β FAQ β Python Signal Handling
β Can Python catch Ctrl+C?
β
 Yes. Use signal.SIGINT to handle keyboard interrupts.
β Can I handle signals in threads?
β No. Signal handlers only work in the main thread.
β How do I stop a long-running loop using signals?
β Set a global flag in the handler and check it inside the loop.
β What signals canβt be handled?
- SIGKILL(9)
- SIGSTOP(19)
These cannot be caught or ignored.
β Whatβs the difference between SIGINT and SIGTERM?
- SIGINT: Sent by keyboard (Ctrl+C)
- SIGTERM: Sent by system/process, often to gracefully stop a program
Share Now :
