Course contentsShow
← Linux
Lesson 479 of 1,8195. Process Management and SignalingFree lesson

Handling Signals in User-Space

Implement custom signal handlers to gracefully clean up application state upon termination.

Graceful Shutdowns with Custom Signal Handlers

In this lesson, you will learn how to intercept signals like SIGTERM or SIGINT to ensure your application cleans up its resources before exiting.

By default, when you press Ctrl+C (sending SIGINT) or stop a service, your process terminates immediately. While this is fine for simple scripts, it can be disastrous for programs that need to save files, close network connections, or remove temporary lock files. To prevent data corruption or orphaned resources, we can "register" a custom signal handler.

How it works

Instead of letting the kernel kill your process instantly, you define a function that runs when a specific signal is received. Inside this function, you can set a "flag"—a simple variable—that tells your main application loop: "It is time to stop." Once your main loop notices this flag, it can break out of its execution, perform the necessary cleanup operations, and exit cleanly.

Here is a conceptual example in C:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

volatile sig_atomic_t keep_running = 1;

void handle_signal(int sig) {
    keep_running = 0; // Signal received, set flag to stop
}

int main() {
    signal(SIGINT, handle_signal); // Catch Ctrl+C

    while (keep_running) {
        // Application logic goes here
    }

    printf("Cleaning up resources...\n");
    // Perform file closures or database commits here
    return 0;
}

Why use a flag?

You might notice the variable keep_running is marked as volatile sig_atomic_t. This is a safety measure. Signal handlers run asynchronously, meaning they can interrupt your code at almost any moment. Using a simple flag ensures that your main loop stays informed without the risk of the program crashing due to memory inconsistency while the handler is executing. By checking this flag in your loop, you ensure the cleanup code runs exactly when it is safe to do so.

Key Takeaway: By registering a custom signal handler, you transition your application from being abruptly killed to exiting gracefully, protecting your data and system integrity.