Linux System Programming · beginner · ~8 min

What are signals in C and Linux?

Understand what a signal is, who sends them, and what happens by default when one arrives.

Overview

A signal is a software interrupt delivered by the kernel to a process. It is essentially a small notification: a number that says "something happened."

Signals come from three sources:

  • Terminal keypresses (for example, Ctrl+C)
  • Other processes, sent with the kill() system call
  • The kernel itself, when a program performs an illegal operation

Why it matters

Every long-running C program needs to handle SIGINT and SIGTERM cleanly. If it does not, ending the program can leave behind locked files, stale network sockets, and lost data.

Signals are also how the Linux kernel reports trouble. When your program crashes, the kernel tells it so by sending a signal.

Core concepts

Signal An integer identifier. The standard signals are numbered 1 to 31. There are also real-time (RT) signals above that range.

Default action What happens when a signal arrives and the program has not arranged otherwise. The default depends on the signal and is one of: terminate, terminate and write a core dump, ignore, stop, or continue.

Catching Replacing the default action with your own code, by installing a handler. You do this with signal() or sigaction() (covered in later lessons).

Uncatchable signals Two signals can never be caught, blocked, or ignored: SIGKILL (9) and SIGSTOP (19).

Standard vs. real-time signals Standard signals coalesce: if several copies arrive before the program reacts, they collapse into a single delivery. Real-time signals (SIGRTMIN to SIGRTMAX) queue, so each one is delivered separately.

Lesson

A signal is a software interrupt that the kernel delivers to a process.

It is the simplest form of inter-process communication (IPC) that Unix offers. There is no shared memory and no socket. There is just a number, such as SIGINT = 2 or SIGTERM = 15, plus the event of delivering it.

Where signals come from

Signals have three sources:

  1. You, through the terminal. Ctrl+C sends SIGINT. Ctrl+\ sends SIGQUIT.
  2. Another process, through kill(pid, signo) or the shell's kill command.
  3. The kernel itself, when your program does something illegal. A bad pointer dereference triggers SIGSEGV. An integer divide-by-zero triggers SIGFPE.

Default actions

Each signal has a default action. Most of the time it is "terminate the process." Sometimes it is "terminate and dump core," and sometimes it is "ignore."

A process can override the default by installing a signal handler (see the next lesson).

The two exceptions

Two signals, SIGKILL and SIGSTOP, cannot be caught, blocked, or ignored. They are the kernel's escape hatch for forcing a process to stop no matter what.

Code examples

/* Run this, then press Ctrl+C. The default SIGINT action terminates. */
#include <stdio.h>
#include <unistd.h>
int main(void) {
    for (int i = 0; i < 30; i++) {
        printf("tick %d\n", i);
        sleep(1);
    }
    return 0;
}

Common mistakes

  • Assuming signals queue like messages. Standard signals coalesce: if several SIGINT are in flight at once, they collapse into a single delivery. If you need true queuing, use real-time signals (SIGRTMIN to SIGRTMAX).
  • Forgetting that SIGKILL and SIGSTOP are uncatchable. No handler will ever run for them.

Real-world uses

  • nginx reloads its configuration when it receives SIGHUP.
  • systemd asks a service to shut down by sending SIGTERM, then sends SIGKILL if the service has not exited after a grace period.
  • gdb and other debuggers intercept SIGSEGV before the kernel terminates your program, so you can inspect its state at the moment of the crash.

Practice tasks

  1. Open the editor and run the tick loop shown above.
  2. From another shell, find the process ID and send kill -USR1 <pid>.
  3. The default action for SIGUSR1 is "terminate." Observe the program stop.

Summary

  • A signal is a kernel-delivered software interrupt, identified by a number.
  • SIGINT (Ctrl+C) and SIGTERM (the default for kill) are the polite "please stop" pair; SIGKILL cannot be refused.
  • The default action depends on the signal; override it by installing a handler.
  • Standard signals coalesce, while real-time signals queue.

Practice with these exercises