COMP 10024 – The UNIX Process Life-Cycle (Week 7)
March 3, 2026 5:59 pmIn our previous sessions, we explored the static world of files and permissions. Today, we move into the dynamic world of the UNIX Kernel. If the file system is a library, then a process is a person currently reading a book. One is storage; the other is action.
1. What exactly is a Process?
A process is a single running copy of a program. It is important to distinguish between the two:
- Program: A static file sitting on your disk (e.g.,
/bin/ls). - Process: The active execution of that file in the system’s memory.
UNIX uses an abstraction called “Virtual Memory.” This means that every process thinks it has the entire system to itself. It doesn’t know about other processes; the Kernel acts as the ultimate mediator, slicing up CPU time and memory so quickly that every process feels like it is the only one running.
2. The Ancestry: Parents and Children
In UNIX, processes are organized in a strict hierarchy. No process is “born” out of thin air.
- The Rule of One: Every process has exactly one parent process.
- The Rule of Many: A process can have zero, one, or many child processes.
- The Ancestor (PID 1): This hierarchy starts with a process called
init(orsystemdin modern Linux). It is the first process started by the Kernel and is the “great-grandparent” of every other process on the system.
| Term | Definition |
|---|---|
| PID | Process ID: A unique integer assigned to every process. |
| PPID | Parent Process ID: The ID of the process that created it. |
| UID | User ID: The user account that the process is running as. |
3. The “Fork and Exec” Model
How do we actually create a new process? UNIX uses a two-step “copy and replace” mechanism.
Step 1: Forking
When a parent process needs to start a task, it performs a fork(). This creates a child that is an exact duplicate of the parent. The child inherits the same memory, the same open files, and the same variables. The only difference is a single “flag” that tells the process “You are the child.”
Step 2: Executing (Exec)
Usually, we don’t want two identical processes. The child then performs an exec(). This wipes the child’s memory and replaces it with a new program. For example, when you type ls in Bash, Bash forks a copy of itself, and that copy execs the ls program.
4. The End of the Road: Exit and Wait
A process dies when its program finishes or it is killed. But even in death, a process has one last job: telling its parent its “life story.”
- Exit Code: When a process finishes, it returns a single integer to the parent.
0usually means “Success.”- Any non-zero number (1-255) usually indicates an error.
- Waiting: A parent process should be waiting (using the
wait()system call) to receive this exit code. Once the parent acknowledges the exit code, the process is completely removed from the system’s memory.
5. The Undead: Zombies and Orphans
What happens when the parent-child relationship breaks down? We get two unique “anomalies”:
| Anomaly | Description |
|---|---|
| Zombie (Defunct) | A child process that has died, but the parent hasn’t “waited” for its exit code yet. It exists only as an entry in the process table, taking up no CPU or RAM. |
| Orphan | A child process whose parent has died. In UNIX, orphans are immediately “adopted” by PID 1 (init), which properly cleans them up when they finish. |
6. Inspecting the System
You can see this life-cycle in action using several built-in UNIX commands. Try typing these into your terminal:
ps: Shows a snapshot of current processes. Useps auxorps -effor a full detailed list.pstree: Visually displays the parent-child relationships in a tree format.top: Provides a real-time, dynamic view of the most active processes.
Pro Tip: If you see a process listed with <defunct> in the ps output, you’ve found a Zombie!
Lab: Managing the UNIX Process Life-Cycle
In this lab, we shift our focus from static files to the active, living entities within UNIX: Processes. You will learn how to monitor, manage, and terminate processes while observing the parent-child relationships that define the system’s hierarchy.
Part 1: Snapshot and Real-Time Monitoring
The first step in process management is seeing what is actually running. We use two main tools: ps for a snapshot and top for a live feed.
- The Basic Snapshot: Type
psin your terminal.Observation: You will likely only see your current shell (bash) and thepscommand itself. - The Big Picture: To see every process running on the system, type:
ps aux- a: Show processes for all users.
- u: Display the user/owner column.
- x: Show processes not attached to a terminal.
- Live Monitoring: Type
top. This is the “Task Manager” of UNIX. Notice how the processes at the top shift as they consume CPU cycles. Press ‘q’ to exit.
Part 2: The Fork and Exec in Action
When you run a command, your shell forks a child. Let’s create a process that lasts long enough for us to inspect it.
- Run a “long-running” command:
sleep 1000.Notice: Your terminal is now “blocked.” You cannot type new commands because the shell is waiting for the child to exit. - Press
Ctrl + C. This sends an Interrupt signal (SIGINT) to the process, killing it and returning control to your shell.
Part 3: Backgrounding and Job Control
Sometimes you want a process to run without blocking your terminal. This is known as “backgrounding” the task.
- Start a task in the background using the ampersand:
sleep 2000 &Output: You will see a number like[1] 12345. The[1]is the Job ID and12345is the PID. - List your active jobs:
jobs - Bring the task back to the foreground:
fg %1. Now the terminal is blocked again. - Suspend it (don’t kill it): Press
Ctrl + Z. This sends the SIGSTOP signal. The process is now “Stopped.” - Resume it in the background:
bg %1.
Part 4: Terminating Processes (The Kill Command)
If a process is behaving badly or you simply want to end it, you use the kill command. In UNIX, kill is a way to send signals to a process.
- Identify the PID of your sleep process:
ps | grep sleep - Send a polite termination signal:
kill [PID](Replace [PID] with your actual number). - Check
jobsto see if it is gone. If a process refuses to die, use the “Sure Kill” (SIGKILL):kill -9 [PID].
Part 5: Investigating the “Life Story” (Exit Codes)
Every process ends with an integer code. In Bash, the special variable $? stores the exit code of the last command run.
- Run a successful command:
ls /Check the exit code:echo $?(Should be 0). - Run a command that fails:
ls /non_existent_folderCheck the exit code:echo $?(Should be non-zero, indicating an error).
Part 6: Visualizing the Ancestry
To see how your shell is the parent of your commands, use pstree.
- Run:
pstree -p [Your_Username] - Look for
bash. You should see it as a branch, and if you have background jobs running, they will appear as “children” stemming from that bash branch.
Summary Challenge: Find a Zombie
Zombies are processes that have finished but haven’t been “reaped” by their parents. To find them, run:
ps aux | grep 'Z'
In the “STAT” column, a Z indicates a defunct/zombie process. If you find one, try to identify its parent PID (PPID) using ps -el!
Categorised in: COMP-10024, Lectures, Portfolio
This post was written by amax
Comments are closed here.