← Operating System Concepts

BOOK NOTES · OPERATING SYSTEMS · CHAPTER 3

Operating System Concepts Chapter 3 — Processes.

operating-systemschapter-3processespcbipcfork

// the one-minute version

A process is a program in action — code plus its current memory, registers, and open files. The OS tracks each with a process control block (PCB), moves it through a small set of states, and switches between processes with a context switch. Processes form a tree via fork/exec. When they must cooperate, they use interprocess communication: shared memory or message passing.

A program sitting on disk is just a file. The moment it runs it becomes a living thing — memory, a place in its execution, resources it holds. That living thing is a process, and managing processes is a core OS job.

01 Program vs process

A program is passive: bytes on disk. A process is active: that program loaded into memory and executing. Run the same program twice and you get two separate processes that don't share memory.

think of it likeA recipe is a program. A cook actually making the dish — ingredients out, current step, half-chopped onions — is a process. Two cooks following the same recipe are two processes.

02 What a process is made of

A process's memory (its address space) has four classic regions, and confusing them is the source of many bugs:

Text

The program's machine code. Read-only.

Data

Global and static variables, fixed in size.

Heap

Memory allocated at runtime (malloc/new). Grows upward as you allocate.

Stack

Function call frames and local variables. Grows downward with each call.

Beyond memory, the process owns CPU state (program counter and registers), a list of open files, and accounting info. Heap and stack grow toward each other in the address space; collide and you get the classic out-of-memory or stack-overflow failure.

03 Process states

At any instant a process is in one state: created (new), ready (waiting only for a CPU), running, waiting (blocked on I/O), or terminated.

newreadyrunningwaitingterminatedtimer: preempted →readyneeds I/OI/O done →ready

Fig 1 — The process state cycle. The scheduler moves processes between ready and running; I/O sends them to waiting and back.

noteOnly one process per CPU core is running at a time. Many can be ready (waiting a turn) or waiting (blocked on I/O). The illusion of "many programs at once" is the OS shuffling processes between these states very fast.

04 The PCB and scheduling queues

For every process the kernel keeps a process control block — state, process ID, program counter, saved registers, memory layout, open files, accounting. The PCB is the process to the kernel. PCBs are linked into queues: a ready queue (processes waiting for a CPU) and device wait queues (processes blocked on a particular device). Scheduling is really the act of moving PCBs between these queues.

05 Context switching

To switch the CPU from process A to B, the kernel saves A's state into A's PCB and loads B's from B's PCB — a context switch. It's pure overhead: no user work happens during it, and it disturbs CPU caches and pipelines.

watch outContext switches aren't free. Saving/restoring registers, flushing pipelines, and cold caches all cost time. A system that switches too often spends its CPU shuffling paperwork instead of working — a real performance trap, and the reason scheduler quanta aren't tiny.

06 Creating and ending processes

Processes form a tree. On UNIX, fork() makes a near-copy of the caller (returning 0 in the child, the child's PID in the parent); exec() then replaces the child's program with a new one. The parent can wait() for the child and collect its exit status.

noteThe fork-then-exec split looks odd but is powerful: between the two calls the child can adjust its environment — redirect files, change permissions, set up pipes — before loading the new program. It's exactly how a shell runs your commands and wires up ls | grep.

Two ending hazards: a zombie is a finished child whose exit status the parent hasn't collected with wait() — it lingers in the process table. An orphan is a child whose parent died first; the system re-parents it to init, which reaps it.

07 Interprocess communication (IPC)

Processes have separate memory, so cooperation needs a deliberate channel. Two models:

Shared memory

The OS sets up a region both processes map and use. Fast (no kernel in the loop after setup), but the processes must coordinate access themselves to avoid races (Chapter 6).

Message passing

Processes send/receive discrete messages through the kernel. Slower (each message crosses into the kernel) but cleaner, and works across machines.

Concrete tools: pipes (a one-way byte stream, as in ls | grep), sockets (endpoints that also work over a network), message queues, and remote procedure calls (Chapter 19). The classic exercise is the producer–consumer problem, returned to in Chapter 7.

common catches & gotchas

  • fork() returns twice — Once in the parent (child's PID) and once in the child (0). Code that ignores the return value and assumes one path is a frequent bug.
  • Zombies vs orphans — A zombie's parent forgot to wait(); an orphan's parent died. Don't mix them up — they're opposite situations.
  • Shared memory needs its own locking — The OS gives you the shared region but not safety. Two processes writing it without synchronization race exactly like threads.
  • Context-switch cost is invisible but real — It doesn't show as a line item, but excessive switching silently tanks throughput.
  • A program is not a process — One program can be many running processes; the file on disk is passive. Exam questions lean on this.

08 Questions students actually ask

Is a process the same as a program?

No. A program is the passive file on disk; a process is that program actively running with its own memory and state. One program can become many processes.

What's in a PCB?

Process state, a unique ID, program counter, saved registers, memory-management info, open-file list, and accounting data — everything needed to pause and resume the process exactly.

Why does fork() return two different values?

So each side knows who it is: the parent receives the child's PID (to track/wait on it), the child receives 0. The single call returns in both processes after the copy.

Why is context switching pure overhead?

During it the CPU does no application work — it just saves one process's state and loads another's, and disturbs caches. Necessary for sharing, but something to minimize.

Shared memory or message passing — which?

Shared memory for maximum speed on one machine when processes can coordinate carefully; message passing for simpler, safer code or communication across machines.

09 Key takeaways

  • A process is a program in execution with its own address space (text/data/heap/stack).
  • Each process is in one state: new, ready, running, waiting, terminated.
  • The PCB stores everything needed to manage and resume a process; PCBs live in scheduling queues.
  • A context switch saves one process and loads another — necessary but pure overhead.
  • fork/exec build a process tree; mind zombies and orphans.
  • Cooperating processes use IPC: shared memory (fast) or message passing (cleaner, networkable).

10 Wrapping up

Processes are the unit the OS schedules, protects, and accounts for. Get states, the PCB, and the context switch clear and the rest follows. Next up: Threads & Concurrency.

← prev: Chapter 2next: Chapter 4 →
© cvam — written in plaintext, served warm