Learning Question
What is a thread, and how is it different from a process?
A process is an OS-managed running instance with its own address space and resources.
A thread is an execution path inside a process.
Multiple threads in one process can run different instruction streams while sharing the same process address space and many process resources.
The first mental model is:
A process is a resource and isolation container. A thread is a schedulable execution context inside that container.
What Threads Share
Threads in the same process usually share:
- virtual address space
- heap memory
- global variables
- loaded code
- open file descriptors
- current process identity and permissions
- many process-level resources
This sharing makes communication between threads easy.
They can access the same memory.
It also makes mistakes easier.
One thread can corrupt data another thread expects to be stable.
What Each Thread Owns
Each thread needs its own execution state.
Important examples include:
- instruction pointer
- CPU registers while running
- stack
- scheduling state
- thread-local storage
- signal mask or related per-thread state on some systems
Separate stacks are especially important.
If two threads used the same call stack for ordinary execution, their function calls and local variables would overwrite each other.
Each thread needs its own call chain.
Threads and Scheduling
Modern operating systems commonly schedule threads, not just whole processes.
If a process has multiple threads, the scheduler may run different threads on different CPU cores at the same time.
It may also preempt one thread and run another.
This means overlapping execution can happen inside one process.
Code that looked sequential in a single-threaded program may become interleaved with code running on another thread.
Shared Memory Creates Data Races
Because threads share an address space, they can access the same variables.
If two threads access the same data at the same time and at least one writes, the result may depend on timing unless synchronization is used.
This is the core reason thread programming requires locks, atomics, condition variables, or other coordination mechanisms.
The operating system provides low-level support for blocking and waking threads.
Language runtimes and libraries often provide higher-level synchronization APIs.
Thread Failure and Process Failure
Threads are not isolated from each other like separate processes.
If one thread corrupts shared memory, the whole process may behave incorrectly.
If one thread causes an unhandled fatal fault, the process may terminate.
The details vary by OS, signal behavior, and runtime, but the boundary is important:
Threads share fate more closely than separate processes because they live inside the same process context.
Why Threads Exist
Threads are useful because they allow one process to have multiple activities in progress.
Examples include:
- serving multiple requests
- doing background work while a UI stays responsive
- overlapping I/O waits with computation
- using multiple CPU cores for parallel work
- separating runtime support work from application work
Threads are not always the best concurrency model, but they are a fundamental OS-supported way to represent multiple execution paths inside one process.
Core Mental Model
A thread is the schedulable execution state inside a process.
The process provides the shared address space and resources.
The thread provides a current path of execution through code.
When reasoning about threaded code, ask:
Is this state per-process and shared, or per-thread and separate?
Final Summary
Threads let one process contain multiple execution paths.
They share process memory and resources, but each thread has its own stack, registers, instruction position, and scheduling state.
That combination makes threads powerful for concurrency and risky when shared memory is not coordinated.