Processes and Threads: Complete Beginner's Guide Guide.
A process is a running program with its own private memory, file handles, and resources. A thread is a smaller execution unit living inside a process — threads share the process's memory and resources but run independently, each with its own stack and program counter.
The distinction decides how programs use multi-core CPUs and how they fail. A video editor renders frames on many threads; a browser isolates each tab in its own process so one crash does not kill the others. Choosing wrong — threads where you needed isolation, processes where you needed shared memory — creates painful bugs.
Key Concepts
- Address space: a process's private memory view. Processes cannot see each other's memory; threads in one process share everything.
- Context switch: the OS swapping one thread's (or process's) state for another's. Thread switches are cheap; process switches cost more because memory mappings change.
- Multithreading: several threads in one process — responsive UIs, split computation across cores.
- Multiprocessing: several processes — crash isolation, sidestepping limits like Python's GIL.
- PCB: the OS's per-process record — ID, state, registers, resources.
- Degree of multiprogramming (n): processes sharing CPU and memory at once.
- Race condition: two threads touch shared data and the result depends on timing.
Formulas
- CPU utilization: U = 1 − p^n, where p is the I/O-wait fraction per process and n the degree of multiprogramming. U ranges 0 to 1.
- Amdahl's law: Speedup = 1 / ((1 − f) + f/s), with f the parallelizable fraction and s the core count.
Assumes identical, independent I/O waits and always-runnable work — an idealization that still guides capacity planning.
Worked Example
Server jobs each spend p = 0.8 (80%) waiting on disk I/O:
- n = 1: U = 1 − 0.8 = 0.2 → 20% CPU usage.
- n = 3: 0.8³ = 0.512 → U = 1 − 0.512 = 0.488 → ~49%.
- n = 5: 0.8⁵ = 0.32768 → U ≈ 0.672 → ~67%.
- n = 10: 0.8¹⁰ ≈ 0.1074 → U ≈ 0.893 → ~89%.
- Lesson: utilization climbs fast then flattens — 5 to 10 processes buys only ~22 points while doubling memory pressure. Systems stop near this knee.
- Amdahl check: f = 0.9 on 8 cores: 1 / (0.1 + 0.9/8) = 1 / 0.2125 ≈ 4.7× — not 8×, because the 10% serial part dominates.
Common Misconceptions
- "More threads always mean faster." Beyond the core count, extra threads add switching overhead. Amdahl's law caps gains at 1/(1−f) regardless.
- "Threads are just lightweight processes." The sharing is the point: threads need synchronization; processes need explicit IPC (pipes, sockets) to talk.
- "A thread crash kills only that thread." No — one address space means a segfault in any thread kills the whole process. Only separate processes isolate crashes.
Real-World Applications
- Web servers: thread or process pools handling thousands of connections.
- Browsers: multi-process tab isolation for stability and security.
- Games: separate threads for rendering, physics, and audio.
- Databases: connection threads sharing buffer caches, with careful locking.
Processes buy isolation at the cost of expensive communication; threads buy cheap sharing at the cost of synchronization. The utilization formula shows why OSes overlap I/O waits across processes — and Amdahl's law shows why cores stop paying off on mostly-serial work.
Related blogs
- CPU Scheduling Algorithms: Complete Beginner's Guide
- Process Synchronization and Semaphores With easy examples.
- Deadlocks: Detection, Prevention and Avoidance For students.
- Memory Management: Paging and Segmentation For students.
- Virtual Memory and Page Replacement With easy examples.
- File Systems: Complete Beginner's Guide With easy examples.