The Big Picture: A Program Is Not a Process
A program is a file sitting on your disk: a recipe in a cookbook. A process is that recipe being cooked right now: a cook, a kitchen, ingredients and a half-finished dish.
Double-click Chrome, and the OS turns the program file into a process. Open it twice, and you get two processes from one program.
What it is: A process is a running program together with everything the OS keeps for it:
| Part of a process | What it is |
|---|---|
| Code | The program's instructions, loaded into memory |
| Address space | Its private virtual memory (Chapter 3) |
| One or more threads | The paths of execution (the "cooks") |
| Open resources | Open files, network connections, windows (called handles on Windows) |
| A process ID (PID) | A unique number the OS uses to name it |
| Security identity | Which user it runs as and what it may do |
The OS keeps all this in a record called the PCB (Process Control Block). On Windows the equivalent kernel structure is called the EPROCESS. Think of the PCB as the OS's file card on each process.
A thread is one line of execution inside a process. A process always has at least one. A browser may have dozens of threads so it can load a page, play a video and run scripts at the same time. Threads of one process share its memory; separate processes do not.
3.1 Process Creation and Termination
What it is: How a process is born, and how it ends.
Creating a process. When you double-click a program, roughly this happens:
1. Something asks the OS to start the program
(you double-click; Explorer calls the OS)
│
2. The OS finds the program file on disk
│
3. It builds a new address space and a PCB
│
4. It maps the program's code into memory
(only the needed pieces are loaded at first, see Section 4)
│
5. It creates the first thread
│
6. The scheduler picks that thread, and the CPU starts
running the program's first instruction
Every process (except the first) has a parent, the process that created it. Processes therefore form a family tree. On Windows, Explorer is the parent of programs you start from the desktop.
Two famous styles exist:
| OS | How a new process is made |
|---|---|
| Linux / Unix | fork() copies the current process, then exec() replaces the copy with the new program |
| Windows | CreateProcess() makes a brand-new process from a program file in one step |
Ending a process. A process ends when:
- It finishes normally and calls an exit function (it can return an exit code, where 0 usually means success).
- It crashes (for example by touching memory it does not own, see Section 4.3).
- Another process or the OS kills it (you press End task in Task Manager).
When a process ends, the OS cleans up: it closes open files, frees its memory, and removes it from its lists. Nothing is left behind, which is one of the OS's most useful promises. (A bug can still leave files or other things behind on disk, but the process's memory and handles are returned.)
On Windows: In PowerShell, run Get-Process | Select-Object -First 10 Name, Id, Threads. Each line is a process with its PID and its thread count. The command tasklist shows a similar list in the old Command Prompt.
3.2 Process States (Running, Waiting, etc.)
What it is: At any moment, each thread is in one of a few states. Most threads are not running. Most are waiting.
| State | Meaning |
|---|---|
| New | Being created |
| Ready | Able to run, waiting for a free CPU core |
| Running | Actually executing on a core right now |
| Waiting (also Blocked) | Cannot continue until something happens, such as a disk read or a key press |
| Terminated | Finished, being cleaned up |
┌──────────── time slice ends ─────────────┐
▼ │
New ──► READY ──── scheduler picks it ──► RUNNING ──────┘
▲ │ │
│ │ └──► Terminated
│ event happens │
└──────── WAITING ◄──────────────┘
(needs disk, key, network...)
The arrows tell the story of a thread's life:
- Ready → Running: the scheduler gives it a core.
- Running → Ready: its turn (time slice) ran out, or a more important thread arrived. This is called preemption (the OS takes the CPU away).
- Running → Waiting: it asked for something slow (like a file). It cannot use the CPU now, so the OS gives the core to someone else.
- Waiting → Ready: the thing it waited for happened (usually an interrupt from the device, Chapter 4).
Why this matters. A normal PC may have 200+ threads but 8 cores. Only 8 can be Running at once. Most are Waiting, which costs almost nothing. That is why an idle PC shows around 1 to 5% CPU even with dozens of programs open.
On Windows: Task Manager's Details tab has a Status column showing Running or Suspended. A UWP app (a Store-style app) that you minimise can be shown as Suspended: the OS has frozen it to save power. The deeper Ready/Waiting states are visible with perfmon counters or the Resource Monitor's CPU tab (look at "Threads" and "Wait Chain").
3.3 Scheduling (CPU Time Allocation)
What it is: The scheduler is the part of the OS that picks which Ready thread runs next on each core, and for how long. It runs every time a thread blocks, ends, or its turn runs out.
The key ideas:
| Idea | Meaning |
|---|---|
| Time slice (or quantum) | The short turn a thread gets, usually a few milliseconds up to about tens of milliseconds |
| Preemption | The OS can interrupt a running thread and take the CPU back |
| Priority | A number saying how important a thread is; higher goes first |
| Run queue | The waiting line of Ready threads |
How does the OS get control to take the CPU back? By a timer interrupt. Remember the timer from Chapter 4 (IRQ 0 in the classic list). A hardware timer fires a regular interrupt. Each time, the OS wakes up, checks whose turn it is, and may swap threads. Without that timer, a program stuck in an endless loop would own the CPU forever.
Common scheduling styles:
| Style | How it works | Good at | Weak at |
|---|---|---|---|
| First-come, first-served | Run in arrival order | Simplicity | One long job blocks everyone |
| Round robin | Equal turns in a circle | Fairness | Ignores importance |
| Priority-based | Highest priority first | Important work | Low priority may starve |
| Multilevel feedback | Mix of priorities that adjust over time | Both interactive and heavy jobs | Complex |
Real systems mix these. Windows uses a priority-based, preemptive scheduler with 32 priority levels (0 to 31). It gives a small boost to threads that just finished waiting (for instance, one that just got a key press), so the PC feels snappy. Linux has its own scheduler; the details differ, the ideas are the same.
Two kinds of thread behaviour:
- I/O-bound threads spend most of their time waiting (a text editor). They need the CPU only for a moment, but quickly. The OS gives them quick access.
- CPU-bound threads use their whole turn (a video encoder). They are fine waiting a little longer.
Many cores. Modern PCs have several cores, and some CPUs mix P-cores (fast) and E-cores (power-saving), as in Figure 7.1. Windows works with the CPU to put heavy, urgent threads on P-cores and background work on E-cores. The OS can also keep a thread on the same core to reuse that core's cache (Chapter 2). That preference is called affinity.
On Windows: Task Manager → Details → right-click a process → Set priority or Set affinity. Do not experiment on important programs. In PowerShell, Get-Process shows a PriorityClass property.
3.4 Context Switching
What it is: A context switch is the act of stopping one thread and starting another on the same core. The context is everything the thread needs to continue exactly where it stopped.
What gets saved and restored:
| Item | Why |
|---|---|
| Registers | The CPU's tiny working storage (Chapter 2), including the program counter (where the thread is in its code) |
| Stack pointer | Where its temporary data lives |
| CPU flags and state | Results of the last comparisons, and so on |
| Address space (if it is a different process) | Point the MMU at the other process's page table (Chapter 3) |
Thread A running ──► timer interrupt!
│
OS saves A's registers into A's record
OS chooses thread B
OS loads B's registers from B's record
│
Thread B running ◄──────┘ (B continues exactly where it left off)
A switch is like putting a bookmark in your book, closing it, and opening someone else's book at their bookmark. Each thread never knows it was paused.
Two sizes of switch:
| Type | Cost |
|---|---|
| Between two threads of the same process | Cheaper: same memory map |
| Between threads of different processes | Costlier: the CPU must switch page tables, and some address-translation cache entries (the TLB, Chapter 3) become useless |
A context switch is pure overhead: it does no work for you. That is why the OS does not switch too often (if time slices were microseconds long, the PC would waste most time switching). Section 7.5 looks at the cost in detail.
Summary
| Topic | Remember this |
|---|---|
| Program vs process | A program is a file; a process is that program running, with its own memory, threads and handles |
| Creation | OS builds an address space and PCB, loads code, creates the first thread |
| Termination | Normal exit, crash or kill; the OS then frees memory and handles |
| States | New, Ready, Running, Waiting, Terminated; most threads are waiting |
| Scheduling | The scheduler picks the next Ready thread; timer interrupts allow preemption |
| Context switch | Save one thread's registers, load another's; useful but costs time |