Chapter 20.1 โ€“ What is a Signal?

 

Chapter 20.1 โ€“ What is a Signal?
Linux System Programming ยท EmbeddedPathashala
๐Ÿ“ก Topic 1 of 19
๐ŸŽฏ Beginner Friendly
๐Ÿ’ป 2 Code Examples
โ“ Interview Q&A

๐Ÿ”‘ Key Terms in This Topic
Signal Software Interrupt Asynchronous Kernel SIGINT Process Notification Hardware Exception IPC

What Exactly is a Signal?

Think of a signal like a phone buzz. You are working on something and suddenly your phone vibrates โ€” that is an interruption. A signal does the same thing to a Linux process. It is a small notification sent to a running process to tell it something has happened.

Signals are often called software interrupts because โ€” just like a hardware interrupt stops the CPU โ€” a signal stops a process’s normal flow and forces it to react.

You cannot always predict exactly when a signal will arrive. That is what makes them asynchronous โ€” they show up at random moments, not at a fixed step in your program.

๐Ÿ‘ค Who Can Send a Signal to a Process?

Three sources can send a signal to a process:

Source Example
๐Ÿ–ฅ๏ธ The Kernel Dividing by zero โ†’ kernel sends SIGFPE
๐Ÿ‘จโ€๐Ÿ’ป Another Process Shell sends SIGTERM to stop a program
๐Ÿ”„ The Process Itself A program calls raise() to signal itself
Note: When used between processes, signals can act as a simple form of IPC (Inter-Process Communication) or as a synchronisation mechanism.

โš™๏ธ How Does the Kernel Decide to Send a Signal?

The kernel generates a signal for a process when:

Event Type What Happens Signal Sent
Hardware Exception Program divides by zero SIGFPE
Hardware Exception Program accesses bad memory address SIGSEGV
Terminal Character User presses Ctrl+C SIGINT
Terminal Character User presses Ctrl+Z SIGTSTP
Software Event Timer expired SIGALRM
Software Event Child process terminated SIGCHLD

๐Ÿ”ข Signals are Just Numbers (with Names)

Every signal is assigned a unique integer number starting from 1. But in your C programs you never use these numbers directly โ€” you always use symbolic names like SIGINT, SIGTERM, etc., defined in <signal.h>.

This is important because the actual number for a given signal can differ between CPU architectures (x86, ARM, MIPS etc.). The symbolic name always works correctly.

Tip: Run kill -l in your terminal to see all signal names and their numbers on your system.

๐Ÿ”„ Signal Lifecycle: Generated โ†’ Pending โ†’ Delivered

A signal goes through three stages:

1. Generated 2. Pending 3. Delivered
An event occurs
(e.g. Ctrl+C pressed)
Signal is waiting
to be handed to the process
(may be blocked)
Process receives the signal
and takes action
๐Ÿ”ด Event fires โณ Queued in kernel โœ… Process reacts

Between generation and delivery, the signal is called a pending signal. The process handles it as soon as it is scheduled to run (or immediately if already running).

๐Ÿ’ป Code Example 1 โ€“ See Signals in Action (Ctrl+C)

This program runs in an infinite loop. When you press Ctrl+C, the kernel sends SIGINT to this process and it terminates. This is the simplest demonstration that signals exist.

/* Example 1: Observe SIGINT from Ctrl+C
   Compile: gcc -o signal_demo signal_demo.c
   Run:     ./signal_demo   then press Ctrl+C */

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    int count = 0;

    printf("Program started. PID = %d\n", getpid());
    printf("Press Ctrl+C to send SIGINT and kill me.\n");

    while (1) {
        printf("Running... count = %d\n", count++);
        sleep(1);   /* sleep 1 second each loop */
    }

    return 0;  /* never reached */
}
What to observe: When you press Ctrl+C the program stops immediately with a “Terminated” or similar message. The kernel delivered SIGINT and the default action (terminate) happened.

๐Ÿ’ป Code Example 2 โ€“ Print Your Own PID and Send Signal Manually

This example prints the PID of the running process. Open a second terminal and use kill -SIGTERM <PID> to manually send a signal to it. This shows that another process (the shell) can send signals.

/* Example 2: Print PID so you can send signal from another terminal
   Compile: gcc -o show_pid show_pid.c
   Run:     ./show_pid
   Then in another terminal: kill -SIGTERM <PID shown> */

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    printf("My PID is: %d\n", getpid());
    printf("Send me a signal from another terminal:\n");
    printf("  kill -SIGTERM %d\n", getpid());
    printf("  kill -SIGKILL %d\n", getpid());
    printf("  kill -SIGINT  %d\n", getpid());

    /* Wait forever doing nothing */
    while (1) {
        sleep(2);
        printf("Still alive...\n");
    }

    return 0;
}
Try it: Send SIGTERM first (process stops gracefully). Then restart and try SIGKILL โ€” it cannot be blocked or caught.

โ“ Interview Questions โ€“ What is a Signal?
Q1. What is a signal in Linux?
A signal is a software notification sent to a process to inform it that a particular event has occurred. It interrupts the normal execution flow of a process, similar to how a hardware interrupt interrupts the CPU.
Q2. Why are signals called “software interrupts”?
Because they interrupt the normal sequential execution of a process at an unpredictable time, just as a hardware interrupt interrupts the CPU. The process stops what it is doing, handles the signal, then resumes (or terminates).
Q3. Name three sources that can generate a signal.
1. The kernel (e.g. hardware exception like divide-by-zero). 2. Another process (e.g. using the kill() system call). 3. The process itself (e.g. calling raise()).
Q4. What is a pending signal?
A signal that has been generated but not yet delivered to the target process is called a pending signal. It stays pending if the process is currently blocking that signal or is not yet scheduled to run.
Q5. Why should you use symbolic names (like SIGINT) instead of signal numbers (like 2) in your code?
Signal numbers can differ across CPU architectures and UNIX implementations. Symbolic names are defined in <signal.h> and always map to the correct number for the platform being compiled on, making the code portable.
Q6. What happens when you press Ctrl+C in the terminal?
The terminal driver sends the SIGINT signal to the foreground process group. The default action for SIGINT is to terminate the process.
Q7. Can signals be used for IPC? Explain briefly.
Yes, signals can be used as a primitive form of IPC. One process can send a signal to another using kill(). However, signals carry very limited information (just the signal number), so they are only suitable for simple notifications, not for transferring data.

Next Topic โ†’

Signal Generation & Delivery โ€“ How exactly does the kernel deliver a signal to a process?

Next: Signal Generation & Delivery โ†’ โ† Chapter Index

Leave a Reply

Your email address will not be published. Required fields are marked *