Process vs Thread
Heavy vs lightweight execution
Processes and threads are both units of execution managed by the operating system, but they differ fundamentally in isolation and resource sharing. Processes are independent with separate memory spaces, while threads share memory within a single process.
Process
A process is an independent instance of a running program with its own virtual memory address space, file descriptors, environment variables, and system resources. Each process is isolated from other processes by the operating system — one process cannot directly access another's memory. Communication between processes (IPC) requires explicit mechanisms like pipes, sockets, shared memory segments, or message queues. Creating a process (fork/spawn) is relatively expensive because the OS must duplicate the memory space and allocate new resources. Processes are the unit of protection in an OS — if one process crashes, others continue running. Each browser tab in Chrome runs as a separate process for this isolation benefit.
Thread
A thread is a lightweight unit of execution within a process. Multiple threads within the same process share the same memory address space, file descriptors, and heap, but each has its own stack and program counter. This shared memory makes communication between threads trivial (just read/write shared variables) but introduces concurrency hazards like race conditions, deadlocks, and data corruption. Creating a thread is much cheaper than a process because there's no memory duplication. Threads are scheduled by the OS kernel (kernel threads) or by a runtime (green threads/goroutines/virtual threads). Most web servers use threads (or lighter equivalents) to handle concurrent requests.
Key Differences
- **Memory**: Processes have separate address spaces. Threads share memory within their parent process. - **Creation cost**: Spawning a process is expensive (memory duplication). Creating a thread is cheap (shared memory, new stack only). - **Communication**: Processes require IPC (pipes, sockets, shared memory). Threads communicate through shared variables (but need synchronization). - **Isolation**: A crashed process doesn't affect others. A crashed thread can bring down the entire process. - **Overhead**: Processes use more RAM and have higher context-switch costs. Threads are lighter. - **Concurrency bugs**: Processes are naturally isolated — fewer concurrency issues. Threads sharing memory are prone to race conditions and require mutexes, semaphores, or other synchronization.
When to Use Each
**Use processes** when you need isolation (a crash in one unit shouldn't affect others), when running untrusted code, when you need true parallelism in languages with a GIL (Python's multiprocessing), or when distributing work across machines. **Use threads** when tasks need to share data frequently, when you need lightweight concurrency within an application, when low-latency communication is important, or when memory efficiency matters. Modern alternatives like goroutines (Go) and virtual threads (Java 21) offer thread-like semantics at even lower cost.
Analogy
**A process** is like a separate apartment in a building — each has its own rooms, kitchen, and bathroom. Residents are completely isolated and must use the building's mail system to communicate with neighbors. If one apartment catches fire, the others are safe. **A thread** is like roommates sharing an apartment — they share the kitchen, bathroom, and living room (memory). Communication is easy (just talk), but they need to coordinate who uses the bathroom to avoid conflicts (synchronization). If one roommate starts a grease fire, the whole apartment burns.