A topic in the Open Knowledge Graph — a free, open map of 15,290 topics and the order to learn them in.

Process Creation: fork() and exec()

College Depth 94 in the knowledge graph ☐ I know this ☆ Set as goal
60topics build on this
356prerequisites beneath it
See this on the map →
Processes and the Process Control BlockKernel Mode and Privilege Levels→→Copy-on-Write Memory OptimizationProcess States and State Transitions+2 more
system-calls process-lifecycle unix-api

Core Idea

Processes are created via system calls like fork() (Unix/Linux) or CreateProcess() (Windows). fork() creates a child process as a copy of the parent; exec() replaces the current process image with a new program. Together, they enable process spawning and program execution in Unix-like systems.

Common Misconceptions

fork() returns twice (it does: once in the parent returning the child's PID, once in the child returning 0). exec() returns on error (it never returns on success; the process image is replaced).

Explainer

You know from the process concept that a process is a running program with its own address space, registers, and OS-managed state. But how does a new process come into existence? In Unix-like systems, the answer is surprisingly simple: every process is created by an existing process using the fork() system call. There is no "create process from scratch" operation — even the first user process (init or systemd) is forked by the kernel during boot. This means every process has a parent, forming a tree rooted at the init process.

When a process calls fork(), the kernel creates a new child process that is a near-exact copy of the parent. The child gets a duplicate of the parent's address space (code, data, heap, stack), the same open file descriptors, and the same register state — including the program counter, so the child resumes execution at the exact same point in the code as the parent. The only difference is the return value of fork(): it returns the child's process ID (PID) to the parent, and 0 to the child. This single difference lets the program branch: `if (fork() == 0) { /* child code */ } else { /* parent code */ }`. It may seem strange that one function call produces two return values, but it makes sense once you realize that after fork(), there are two independent processes running the same code — each receives its own return value.

Fork alone is only half the story. A child that is an exact copy of its parent is rarely useful — you usually want the child to run a different program. That is where exec() comes in. The exec family of system calls (execl, execv, execvp, etc.) replaces the current process's entire address space with a new program loaded from an executable file. The process ID stays the same, open file descriptors are preserved (unless marked close-on-exec), but the code, data, stack, and heap are replaced completely. Exec never returns on success because there is nothing to return to — the old program is gone. It only returns if loading the new program fails (e.g., file not found, permission denied).

The fork-then-exec pattern is the standard Unix idiom for launching programs. A shell, for example, forks a child process, and the child calls exec to run the command you typed. The parent (the shell) waits for the child to finish using wait() or waitpid(), then prints the next prompt. This two-step design is deliberate and powerful: the window between fork and exec gives the child a chance to set up its environment — redirect file descriptors (for I/O redirection like `> output.txt`), change the working directory, adjust signal handlers, or drop privileges — before the new program starts. Combining these simple primitives gives Unix its characteristic composability: pipes, background jobs, and process supervision all emerge from fork, exec, and wait.

Practice Questions 5 questions

Prerequisite Chain

Understanding Zero → The Number Zero → Counting to Five → Counting to 10 → Counting to 20 → Counting a Set of Objects Up to 20 → Cardinality: The Last Number Counted → Matching Numerals to Quantities → Subitizing Small Quantities → Addition Within 10 → Number Bonds to 10 → Addition Within 20 → Doubles and Near Doubles → Doubles Facts Within 10 → Near Doubles Facts Within 20 → Mental Math Strategies for Addition → Mental Math: Adding and Subtracting Tens → Addition Within 100 → Repeated Addition as Multiplication → Multiplication as Equal Groups → Multiplication: Arrays → Basic Multiplication Facts (0s, 1s, 2s, 5s, 10s) → Multiplication Facts Within 100 → Division as Equal Sharing → Division as Grouping (Measurement Division) → Division: Grouping (Repeated Subtraction) Model → Division: Fair Sharing Model → Division as Equal Sharing → Division as Grouping → Basic Division Facts → Division Facts Within 100 → Multiplication and Division Fact Families → Relationship Between Multiplication and Division → Division Facts as Inverse of Multiplication → Remainders and Quotients in Division → Division Word Problems → Multi-Step Word Problems → Solving Multi-Step Word Problems → Multiplication Word Problems → Division Word Problems → Introduction to Long Division → Factors and Multiples → Prime and Composite Numbers → Equivalent Fractions → Relating Fractions and Decimals → Decimal Place Value → Integers and the Number Line → Comparing and Ordering Integers → Absolute Value → Adding Integers → Subtracting Integers → Multiplying Integers → Introduction to Exponents → Order of Operations → Integer Order of Operations → Variable Expressions → The Distributive Property → Variables and Expressions Review → Introduction to Polynomials → Adding and Subtracting Polynomials → Multiplying Polynomials → Factorial → Permutations → Combinations → Counting Principles: Addition and Multiplication Rules → Introduction to Graph Theory → Propositional Logic Foundations → Logical Equivalences → Boolean Algebra → Boolean Type and Truth Values → Comparison Operators and Boolean Tests → Logical Operators and Boolean Algebra → Boolean Algebra and Fundamental Laws → Logic Gates Fundamentals → Implementing Boolean Functions with Gates → Karnaugh Map Simplification → Combinational Circuit Design → Flip-Flops and Latches → Binary Counters: Design and Analysis → Binary Arithmetic → Fixed-Point Number Representation → Two's Complement Representation → Overflow and Underflow Detection → Binary Adders: Half-Adders and Full-Adders → Full Adder and Carry Propagation → Carry Lookahead Adder Design → Half Adder Circuit Design → Multiplication Circuit Design → Sequential Circuit Design → Registers and Register Files → Instruction Set Architecture (ISA) → Kernel Architecture and OS Structure → System Calls and User/Kernel Mode → Processes and the Process Control Block → Process Creation: fork() and exec()

Longest path: 95 steps · 356 total prerequisite topics

Prerequisites (2)

Leads To (4)