CPU Scheduling

A core executes one instruction stream at a time. Your laptop has hundreds of processes "running." The scheduler picks who gets the core next, for how long, and who gets interrupted.

If the scheduler is unfair, the UI stutters while a compile hogs the machine. If it switches too often, the machine spends its life saving registers instead of doing work.

[!TIP] ELI5: One cashier, many carts The CPU is a cashier. FCFS is a single line — a full cart blocks gum. SJF serves the smallest cart first — gum wins, the turkey shopper starves. Round robin scans five items then rotates. Linux CFS tries to give everyone a fair share of cashier-time, with a boost for the person who just clicked a mouse (interactive).

1. Preemption and the time slice

Non-preemptive: once a process has the CPU, it keeps it until it blocks (I/O) or exits. One infinite loop freezes the machine. Old batch systems could live with this. Your phone cannot.

Preemptive: the kernel can interrupt after a quantum (time slice) or when a more important thread wakes. Modern desktops, servers, and phones are preemptive.

A process also blocks on purpose: waiting on disk, a lock, a network packet. That is not a failure; it is how the scheduler finds someone else to run.

2. Context switch (the tax)

When the kernel switches from process A to B it must:

That costs microseconds and cache warmth. A 1ms quantum with 50µs switches wastes 5% of the core. A 100ms quantum feels laggy for typing. Scheduling is this trade-off.

Threads in the same process still context-switch CPU state but share the address space — cheaper than switching processes, not free.

3. Textbook algorithms (and their failure mode)

FCFS (first-come, first-served). Simple. Convoy effect: a long CPU hog at the head of the queue delays everyone.

SJF (shortest job first). Ideal average wait if you magically know burst lengths. You do not. Starvation: a long job waits forever if short jobs keep arriving.

Round robin. Ready queue is a ring. Each thread runs for a quantum. Fair-ish. Quantum too short → switch storm. Too long → interactive lag.

Priority. High priority runs first. Without aging (priority slowly rises while waiting), low priority starves. Priority inversion (low holds a lock high needs) is a real bug; priority inheritance is the usual fix.

4. What Linux actually does (enough to be useful)

Linux's default is CFS (Completely Fair Scheduler): it tracks how much CPU time each runnable task has gotten and runs the one that is most "behind," using a red-black tree, not a simple queue. Interactive tasks that sleep a lot look "behind" when they wake, so they get the core quickly — that is why typing stays snappy during a compile.

You will also meet:

top          # STAT: R running, S sleeping, D uninterruptible I/O
ps -eo pid,ni,pri,cmd | head

If a process is always D, you do not have a scheduling problem — you have disk or lock I/O.

5. Why application engineers care

What to remember