In this lesson, you will learn how a kill command travels from your terminal through the kernel to actually stop a target process.
When you type kill -SIGTERM <PID> in your terminal, you aren't actually "killing" anything yourself. Instead, you are making a system call to the Linux kernel, acting as the intermediary. Here is the step-by-step lifecycle of that request:
1. The System Call Initiation
Your shell executes the kill() system call. The kernel immediately validates your identity; it checks if your current User ID matches the target process’s owner, or if you have the necessary privileges to send signals to that process. If you don't have permission, the kernel rejects the request immediately.
2. Searching the Task List
Once authorized, the kernel looks up the target process by its PID in the internal process table. It locates the task_struct (the kernel's data structure that tracks everything about a process, which we learned about in our anatomy lesson).
3. Updating the Signal Pending Mask
The kernel does not immediately interrupt the target process. Instead, it updates the target process’s "pending signals" bitmask. Think of this as a message waiting in the process's mailbox.
/* Conceptually, the kernel sets a bit in the target process structure */
target_process->pending_signals |= (1 << SIGTERM);
4. The Wake-up Call
The kernel marks the target process as "ready to run." If the process was blocked or waiting (e.g., in an I/O wait state), the kernel wakes it up and schedules it to run on a CPU core.
5. Delivery and Execution
The next time the target process transitions from kernel-space back to user-space, the kernel checks the "pending signals" mask. Seeing the SIGTERM bit is set, it forces the process to pause its normal execution. The kernel either executes a default action (like terminating the process) or jumps to a custom signal handler function if the programmer has defined one.
If no special handler is set, the kernel cleans up the process's resources, closes its file descriptors, and transitions it into a zombie state until the parent process acknowledges the exit.
Key Takeaway: A kill request is a kernel-mediated notification that updates a process’s internal signal mask, which the kernel then forces the process to acknowledge during its next transition to user-space.