Processes and signals
Every program you run becomes a process: a running copy with its own number, the PID, and a row in the kernel's process table. Follow one small Python program from start to finish: the shell starts it with fork and execve, kill sends it SIGTERM, its handler cleans up, its row turns into a zombie, and bash collects its exit status. Then see why SIGKILL (kill -9) is the last resort.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01You type python3 worker.py & and bash prints [1] 4242. What is 4242?
Bash prints the job number in brackets, then the PID the kernel gave the new process. Here: job 1, PID 4242.
02What does kill 4242 do when you give it no option?
kill only sends a signal. The default signal is SIGTERM. Its default action ends the process, but a program can set a handler (like bye in worker.py) to tidy up before it exits.
03Why did bye never run when we sent kill -9?
SIGKILL (and SIGSTOP) can never be caught. That is why it always works, and also why the program gets no chance to save or tidy anything. Try plain kill (SIGTERM) first.
04A row in ps shows the state Z. What does it mean?
Z is a zombie (ps shows it as <defunct>). Only the row is left, holding the PID and exit status, until the parent calls wait. R means running and S means sleeping.
05Which signal does pressing Ctrl-C send to the program running in the foreground?
Ctrl-C makes the terminal send SIGINT (interrupt) to the foreground job. A job started with & runs in the background, so Ctrl-C does not reach it; use kill instead.
Glossary
- Process
- A program that is running: its code, its memory and its open files. Run the same program twice and you get two processes.
- PID
- Process ID: the number the kernel gives each process, for example 4242. Commands like ps and kill use it.
- PPID
- Parent process ID: the PID of the process that started this one. A program you start from bash has bash's PID as its PPID.
- fork and execve
- The two system calls a shell uses to start a program: fork makes a copy of the shell, execve loads the new program into that copy.
- Signal
- A small numbered message the kernel delivers to a process, such as SIGINT (2), SIGTERM (15) or SIGKILL (9).
- Signal handler
- A function a program asks the kernel to run when a given signal arrives, instead of the default action.
- Exit status
- A number a process leaves behind when it ends. 0 means success; anything else usually means an error.
- Zombie
- A process that has ended but whose parent has not yet collected its exit status with wait. Only its row is left (state Z).
Notes and sources
- The PIDs (1200 for bash, 1100 for its parent, 4242 for the program) are examples. Your machine picks its own.
- The terminal card is tidied. In a real terminal "cleaning up" may appear just after a new $ prompt, and bash prints the Done line the next time it shows a prompt (press Enter), or at once after set -b. Bash also pads the line with more spaces.
- ps -o pid,ppid,stat,comm shows the same columns. ps adds extra letters to STAT, such as s (session leader) and + (in the foreground), so bash usually shows as Ss or Ss+. The pending column is in /proc/<PID>/status as SigPnd.
- Ctrl-C makes the terminal send SIGINT to the foreground job only. A job started with & is in the background, so Ctrl-C would not reach it; that is why we use kill.
- A zombie uses no memory or CPU, only its row. If a parent ends without collecting its children, they are handed to another process (init, PID 1, or a "subreaper") that collects them.
- Linux man-pages: signal(7), overview of signals (standard signals, numbers, actions)
- Linux man-pages: kill(1), send a signal to a process
- Linux man-pages: kill(2), the kill system call
- Linux man-pages: fork(2), create a child process
- Linux man-pages: execve(2), execute a program
- Linux man-pages: wait(2), wait for a process to change state (zombies)
- Linux man-pages: ps(1), process state codes
- Linux man-pages: proc_pid_status(5), /proc/<pid>/status (State, PPid, SigPnd)
- Linux man-pages: termios(3), the INTR character (Ctrl-C sends SIGINT)
- The Linux kernel documentation: The /proc Filesystem
- GNU Bash Reference Manual: Job Control Basics and the kill builtin
- Python documentation: signal, set handlers for asynchronous events
- Python documentation: built-in exceptions, SystemExit
- R. and A. Arpaci-Dusseau, Operating Systems: Three Easy Pieces, ch. 5 Process API
Quiz Unlocks after the last step.