What a process is
A process is a program that is running. The kernel gives each process a number, its PID, and keeps a row about it in the process table. Your shell, bash, is a process too: here its PID is 1200.
Starting a process
We start a small Python program that waits five minutes: python3 worker.py &. The & at the end runs it in the background, so the shell gives the prompt back at once instead of waiting for it.
The shell asks the kernel to fork, which copies the shell, then execve, which loads python3 into the copy. The new process gets PID 4242; its parent PID (PPID) is 1200. Bash prints [1] 4242: job 1, PID 4242.
worker.py first tells the kernel: if SIGTERM arrives, run my function bye. That function is a signal handler. Then the program sleeps. In the table its state goes from R (running) to S (sleeping: waiting for something).
Signals
A signal is a small numbered message the kernel delivers to a process. SIGINT (2) is what Ctrl-C sends. SIGTERM (15) asks a process to stop. SIGKILL (9) stops it at once. Each has a default action, often ending the process.
We type kill 4242. Despite its name, kill only sends a signal; with no option it sends SIGTERM. Bash runs kill itself and makes the kill system call. The kernel marks SIGTERM as pending for 4242.
The kernel wakes process 4242 and delivers SIGTERM. A handler is set, so instead of the default action, ending the process, Python calls bye. The state goes back to R: it is running again.
bye prints cleaning up, then raises SystemExit(0). The program ends on its own terms, after tidying up, with exit status 0, which means success. That is why programs are asked with SIGTERM first.
Ending
The process has ended and the kernel frees its memory, but its row stays, in state Z: a zombie. The row only keeps the PID and the exit status, until the parent collects them.
Bash collects the status with the wait system call. Now the kernel removes the row, and PID 4242 can be reused. Bash reports the job: [1]+ Done, because the exit status was 0.
Had we typed kill -9 4242, the kernel would send SIGKILL. It cannot be caught, blocked or ignored, so bye never runs: the kernel ends the process at once, with no clean-up. Bash reports Killed.
What happens
;; step 1/11 · process
process a program that is running:
its code, its memory, its open files
PID the process ID, a number the kernel gives it
process table the kernel's list: one row per process
bash PID 1200 parent 1100 state S
see yours: echo $$ (the shell's own PID)
ps -o pid,ppid,stat,comm
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.