OS · Processes & Threads

Processes & Threads

What a running program actually is — address space, the process lifecycle, and why threads are lighter.

Operating Systems Basics → Interview
01

What is a Process?

A process is a program in execution — an instance with its own address space (code, data, heap, stack), a set of registers, a program counter, and OS bookkeeping in a Process Control Block (PCB). A program on disk is passive; a process is the active, running thing.

Stack ↓ Heap ↑ Data (globals) Text (code) high addr low addr
02

Process States

The OS moves a process through states as it runs, waits and is scheduled. The classic five-state model:

StateMeaning
NewBeing created
ReadyLoaded, waiting for the CPU
RunningExecuting on the CPU right now
WaitingBlocked on I/O or an event
TerminatedFinished; PCB about to be reclaimed
Only one process per CPU core is Running at a time. The scheduler cycles Ready ⇄ Running; I/O bounces Running → Waiting → Ready.
03

Process vs Thread

A thread is a unit of execution inside a process. Threads of one process share its address space (heap, globals, open files) but each has its own stack, registers and program counter. That sharing makes threads cheap to create and switch — and dangerous, because they can stomp on shared memory.

Threads share
  • Heap & globals
Threads have their own
  • Stack
AspectProcessThread
Address spacePrivateShared with siblings
Creation costHigh (fork)Low
Context switchExpensive (TLB flush)Cheap
Crash blast radiusIsolatedCan take down the process
CommunicationIPC (pipes, sockets)Shared memory directly
04

Creating a Process — fork()

On Unix, fork() clones the calling process. It returns twice: 0 in the child, the child’s PID in the parent. exec() then replaces the child’s image with a new program — the fork-exec pattern behind every shell command.

C — fork / exec
#include <unistd.h>

pid_t pid = fork();
if (pid == 0) {
    // child: replace image with /bin/ls
    execlp("ls", "ls", "-l", NULL);
} else {
    wait(NULL);   // parent reaps the child
}
A child whose parent never wait()s becomes a zombie (dead but still in the table). A child whose parent dies first becomes an orphan, re-parented to init/systemd.
05

Inter-Process Communication (IPC)

Because processes don’t share memory, they need explicit channels to talk. Common IPC mechanisms, from simplest to most flexible:

MechanismUse it for
PipesOne-way byte stream between related processes (ls | grep)
Named pipes (FIFO)Same, but between unrelated processes
Shared memoryFastest — a common memory region, but you must synchronize
Message queuesStructured, ordered messages
SocketsAcross machines, or local (Unix domain sockets)
06

Interview Questions

Process vs thread — one sentence.

A process is an isolated program with its own address space; a thread is a lighter execution unit inside a process that shares that address space but keeps its own stack and registers.

Why does fork() return twice?

It creates a near-identical copy of the process; execution continues in both the parent and the new child from the same point, so the single call yields a return in each — 0 in the child, the child PID in the parent.

What is a zombie process and how do you avoid it?

A terminated child whose exit status hasn’t been reaped. The parent must call wait()/waitpid(); otherwise the entry lingers. In practice, handle SIGCHLD or double-fork.

Context switch — what makes it expensive?

Saving/restoring registers and PC, switching the memory map, and (for processes) flushing the TLB and cache locality. Thread switches within a process skip the address-space swap, so they’re cheaper.

Quick Quiz

1. What do threads of the same process NOT share?
2. fork() returns ___ in the child process.
3. A process blocked on disk I/O is in which state?
4. A terminated child not yet reaped by its parent is a…
5. Fastest IPC mechanism (but needs synchronization)?