Process vs Program
A program is a passive file on disk — a sequence of instructions. A process is the active incarnation of that program: the OS has loaded its code and data into memory, allocated a process identifier (PID), and started tracking its execution state. One program can produce many processes (each terminal window running bash is a separate process of the same program).
The Process Control Block (PCB)
Every process has a Process Control Block (PCB) — a kernel data structure holding everything the OS needs to manage it:
- Process state (new, ready, running, blocked, terminated)
- Program counter and CPU registers (so execution can be resumed after a switch)
- Memory limits and page-table pointer
- Open file descriptors
- Scheduling information (priority, queue pointers)
- Accounting (CPU used, elapsed time)
The PCB is the kernel’s file on a process: context switching is fundamentally swapping the register context of two PCBs.
Process States
A process is never always-running; it moves through a lifecycle:
- New — being created (via
forkon Unix). - Ready — loaded into memory, waiting for the CPU.
- Running — currently executing on the CPU.
- Blocked (waiting) — waiting for an event (I/O, lock, message).
- Terminated — finished; PCB may remain briefly for the parent to read its exit status.
State transitions are the heart of scheduling: a scheduler moves ready processes to the running state, and running processes back to ready (preemption) or to blocked (I/O wait).
Context Switching
Switching the CPU from one process to another has a cost: the OS must save the running process’s registers and PC to its PCB, load the next process’s saved context, and flush/refill the TLB. This overhead — microseconds per switch, but multiplied by thousands of switches per second — is why scheduling is a real engineering problem, not just a policy nicety.
CPU Scheduling
The scheduler answers one question: which ready process runs next? Its choice is governed by metrics:
- Turnaround time = completion − arrival
- Waiting time = turnaround − burst
- Response time = first-CPU time − arrival
The interactive visualizer above animates each algorithm as a Gantt chart and computes these metrics live.
FCFS — First-Come, First-Served
The simplest policy: run processes in arrival order, each to completion. Non-preemptive — once a process owns the CPU it keeps it. Fair in order but suffers convoy effect: one long burst holds up many short jobs behind it, inflating average waiting time.
SJF — Shortest Job First
When the CPU frees, run the shortest ready burst. Non-preemptive SJF provably minimizes average waiting time among non-preemptive policies. The catch: it can starve long jobs if a stream of short jobs keeps arriving, and you need to predict burst lengths.
SRTF — Shortest Remaining Time First
The preemptive version: at every arrival, if a new process has less remaining time than the running one, preempt. SRTF is optimal for average turnaround — but it churns through context switches and can starve long processes even worse than SJF.
Round Robin
Give each process a time quantum (e.g. 2 units), then rotate the CPU to the next process in a FIFO ready queue. Preemptive, fair, starvation-free, and the interactive-timesharing workhorse. Larger quanta reduce switching overhead but increase response time; smaller quanta give snappier response at higher cost. With an infinite quantum, Round Robin degenerates into FCFS.
Priority Scheduling
Always run the highest-priority (lowest-number) ready process, preempting when a higher-priority process arrives. Gives urgent work the CPU immediately but risks starvation of low-priority processes — mitigated with aging (gradually raising the priority of waiting processes).
Worked Example
Five processes arrive at times 0–5 with bursts 6, 8, 7, 3, 4:
| PID | Arrival | Burst |
|---|---|---|
| P1 | 0 | 6 |
| P2 | 1 | 8 |
| P3 | 2 | 7 |
| P4 | 3 | 3 |
| P5 | 5 | 4 |
Try each algorithm in the visualizer and watch how the Gantt chart and the average turnaround/waiting metrics change. Notice SRTF’s preemptions (P1 yields mid-run when a shorter-remaining process appears) and Round Robin’s quantum slices.
When Each Policy Is the Right Tool
| Situation | Scheduler |
|---|---|
| Batch throughput, minimal overhead | FCFS or SJF |
| Interactive systems need snappy response | Round Robin with small quantum |
| Real-time/urgent work must jump the queue | Priority (with aging) |
| Min average turnaround, can tolerate preemption | SRTF |
| Fairness and no starvation matter most | Round Robin |
Practice Trajectory
- Given a process table, hand-trace FCFS and Round Robin, drawing the Gantt chart and computing turnaround/waiting/response.
- Explain why SJF is optimal for non-preemptive average waiting time, and when it starves.
- Trace SRTF for the same inputs and note exactly where preemption happens.
- Compute the context-switch overhead of Round Robin as a function of quantum and switch cost.
- Explain how aging fixes priority starvation.
When It’s the Right Tool
| Situation | Takeaway |
|---|---|
| Learning OS internals | Scheduling is where policy meets hardware cost |
| Building interactive/timesharing systems | Round Robin with a tuned quantum |
| Real-time constraints | Priority + preemption + aging |
| Server batch workloads | FCFS/SJF keep overhead low |