Lecture 2 of 1417 minInteractiveFree lecture

Processes: programs in motion

A program is a file; a process is that program running, with its own memory, open files and state. Move a process through its life cycle, and look inside the address space every process gets.

In this lecture you will

  • Distinguish a program from a process
  • Describe the process life cycle and what causes each transition
  • Explain what the kernel stores about each process
  • Describe the layout of a process address space — text, data, heap and stack

A program is a passive thing: an executable file sitting on disk. A process is a program in motion — loaded into memory and running, with a current instruction, variables, open files and network connections. Run the same program three times, and you get three processes, each unaware of the others.

What the kernel knows about a process

For every process, the kernel keeps a record called the process control block (PCB). It holds everything needed to stop the process and resume it later as if nothing had happened:

Process ID (PID)
A number that identifies the process — what tools like top, ps and Task Manager show.
State
Whether it is running, ready to run, or waiting for something.
Saved registers
The program counter and other CPU registers, saved whenever the process is paused.
Memory map
Which parts of virtual memory the process owns, and where they live in physical memory.
Open files and sockets
A table of everything the process has open — the file descriptors from lecture 1.
Owner and limits
Which user it runs as, its permissions, priority and resource limits.

The life cycle

A process doesn’t run continuously. At any moment it is in one of a few states, and events move it between them. Drive a process through its life yourself — only the transitions that make sense from the current state are enabled.

InteractiveThe process life cycleUse the transition buttons
Loading visual…

Each move between running and another state is a context switch: the kernel saves one process’s registers into its PCB and restores another’s. It takes only microseconds, but it isn’t free — the new process also starts with cold CPU caches. Systems running thousands of busy processes can spend a noticeable share of time just switching.

Here is one switch in slow motion:

AnimationA context switch
Loading animation…
  1. A is runningProcess A’s values fill the CPU registers: where it is in its code, its stack, its working data. B is ready, its registers saved in its PCB.
  2. A timer interruptA timer interrupt fires and the CPU jumps into the kernel. A didn’t ask to stop: this is preemption, and it is how one busy program can’t hog a core.
  3. Save AThe kernel copies A’s registers into A’s process control block and marks A ready.
  4. Restore BIt loads B’s saved registers, switches to B’s page tables and returns to user mode. B continues exactly where it left off.
  5. Cold cachesThe switch itself takes microseconds, but B’s data isn’t in the CPU caches yet. Refilling them is often the bigger hidden cost.

Creating processes

On Linux and macOS, new processes are traditionally created in two steps. fork makes an almost exact copy of the current process; exec replaces the copy’s program with a new one. When you type a command in a shell, the shell forks itself and the child execs your program. Windows combines both steps into a single CreateProcess call. Either way, the new process is a child of the one that created it, which is why processes form a tree.

Watch a shell run ls -l:

Animationfork, exec, exit, wait
Loading animation…
  1. The shellYou type ls -l into bash, process 1200. bash can’t turn itself into ls: it must survive to show the next prompt.
  2. fork()fork() creates a child, process 1201, as a near-exact copy of bash. Memory is shared copy-on-write, so the copy is cheap. fork returns 1201 to the parent and 0 to the child — that is how each knows which one it is.
  3. exec()The child calls exec to run /usr/bin/ls. Its code and memory are replaced; its PID and open files, including the terminal, stay the same.
  4. Run and exitThe ls program writes to the terminal and calls exit(0). Until the parent collects its exit status, the finished child lingers as a zombie.
  5. wait()The shell’s wait() returns the exit status — available as $? — and the child is gone. Nearly every command you run lives this life.

Inside a process: the address space

Every process gets its own virtual address space — an apparently private range of memory addresses, laid out the same way in every process. Step through its regions:

InteractiveThe address space of a process
Loading visual…
  1. Text: the codeThe program’s machine instructions, loaded from the executable. Marked read-only and executable, so a bug can’t overwrite the code.
  2. Data: global variablesGlobal and static variables that exist for the whole life of the program.
  3. Heap: memory on demandSpace for objects created while the program runs — every new list, object or buffer. It grows upward as the program allocates more.
  4. Stack: function callsOne frame per active function call, holding local variables and the return address. It grows downward and shrinks as functions return.
  5. Room to growThe gap between heap and stack lets both grow. Stack overflows happen when deep or infinite recursion runs out of stack space.

Because every process has its own address space, the same address in two processes refers to two different pieces of physical memory. One process simply cannot name another’s memory — the foundation of isolation. Lecture 5 shows how the hardware makes this work.

With many processes ready to run and only a few CPU cores, the kernel must constantly choose who goes next. That is scheduling — the subject of the next lecture.

Key takeaways

  • A process is a running instance of a program, with its own address space, registers, open files and identity.
  • Processes move between ready, running and waiting states; context switches save and restore their state.
  • The kernel tracks each process in a process control block — its ID, state, registers, memory map and open files.
  • Each process sees the same layout — code, data, a heap that grows up and a stack that grows down.

Check your understanding

3 questions · answers explained

Q1You open three windows of the same text editor. How many programs and processes are there, typically?

The program — the executable file — exists once. Each launch creates a separate process with its own memory and state, although modern apps may also share work between processes.

Q2A process asks to read from the network and no data has arrived yet. Which state does it move to?

It cannot make progress until data arrives, so it gives up the CPU and waits. When the data arrives, an interrupt moves it back to ready — it still has to wait for its turn to run.

Q3Where are local variables of a function stored while the function runs?

Each function call pushes a frame onto the stack holding its local variables and return address; the frame is removed when the function returns. Longer-lived objects go on the heap.