Hone logo
Hone
Problems

Graceful Shutdown: Implementing Signal Handling in Python

Many applications need to respond to external events, such as termination requests from the operating system or user. Implementing signal handling allows your Python program to gracefully shut down, clean up resources, and avoid abrupt termination. This challenge focuses on using Python's signal module to catch common signals and execute custom logic.

Problem Description

Your task is to create a Python script that listens for specific operating system signals and performs a defined action when those signals are received. Specifically, you need to handle the SIGINT (Interrupt signal, typically sent by Ctrl+C) and SIGTERM (Termination signal, often sent by kill commands).

Key Requirements:

  1. Register Signal Handlers: Implement functions that will be executed when SIGINT and SIGTERM are received.
  2. Graceful Shutdown: When either signal is caught, the program should print a "Shutting down..." message, perform any necessary cleanup (simulated in this case), and then exit cleanly.
  3. Continuous Operation (until signal): The program should continue to run and perhaps perform some ongoing task until a signal is received.
  4. Default Behavior Preservation (optional but good practice): For signals not explicitly handled, the default system behavior should be preserved.

Expected Behavior:

  • The program will start and run, printing messages periodically to indicate it's alive.
  • When Ctrl+C is pressed in the terminal, the program should print "Received SIGINT. Shutting down gracefully..." and then exit.
  • If the program is terminated by a kill command (e.g., kill <pid>), it should print "Received SIGTERM. Shutting down gracefully..." and then exit.

Edge Cases to Consider:

  • What happens if a signal is received while the program is performing a lengthy operation? (For this challenge, assume operations are short or can be interrupted).
  • How to ensure the program exits with a success code after handling the signal.

Examples

Example 1:

Input: The user runs the Python script in a terminal.

Output:
Program is running... (This will print every few seconds)
Program is running...
Program is running...
^C
Received SIGINT. Shutting down gracefully...
(Program exits)

Explanation:
The user presses Ctrl+C, sending the SIGINT signal. The registered handler catches this signal, prints the shutdown message, and the program terminates.

Example 2:

Input: The user runs the Python script and then sends a SIGTERM signal from another terminal using `kill <process_id>`.

Output:
Program is running... (This will print every few seconds)
Program is running...
Received SIGTERM. Shutting down gracefully...
(Program exits)

Explanation:
The SIGTERM signal is sent to the process. The registered handler catches this signal, prints the shutdown message, and the program terminates.

Constraints

  • The Python script should be written in Python 3.
  • The program should run indefinitely until a signal is received.
  • The output messages should be clear and informative.
  • The program must exit cleanly, typically with an exit code of 0 for successful shutdown.

Notes

  • You will need to import the signal and time modules.
  • Consider using signal.signal(signalnum, handler) to register your custom functions.
  • A loop with time.sleep() can be used to simulate the program's ongoing work.
  • The sys.exit() function is useful for controlled program termination.
  • The signal.SIGINT and signal.SIGTERM constants represent the signals you need to handle.
  • For a graceful exit, you might want to set a flag within your signal handler that the main loop checks to break out of its execution.
Loading editor...
python