Threads and Process Creation in Operating Systems: fork(), Thread Models and Worked Examples
Build a reliable model of processes and threads, then trace conditional fork() calls across six named process paths without losing track of return values.
KnowledgeGate Team
Exam prep & CS education

A program is not a process, and a process is not a thread. That distinction becomes especially important when three lines containing fork() produce more processes than there are calls. Resource ownership, process creation and thread creation follow one consistent model in the named-PID trace. POSIX-style fork(), exec() and wait() form the exam model; the core resource-sharing ideas also apply to systems that expose different calls.
For the broader ownership boundary, copy-on-write, context-switch cost and symbolic six-process tree, use Threads and Process Creation in OS: fork() Worked Examples. A separate PID ledger follows exactly which return values PIDs 4000 to 4005 hold after a conditional fork() trace, and why exec(), waitpid() and exit status 7 do not add another process. The thread-model contrast exposes the shared-state boundary between creating a thread and creating a process.
Related reading: thread and process MCQs and process state questions.
1. Process and Thread Boundaries for the PID Ledger
A program is a passive set of instructions stored on disk. A process is a running instance of a program, identified by a PID and given a virtual address space plus resources managed by the operating system. A thread is an execution path inside that process.
The ownership rule is simple: processes own resource containers, while threads execute within them.
Suppose process PID 4000 contains code, a heap variable counter = 12 and open file descriptor 3. Its threads T1 and T2 share all three. T1 still needs its own program counter, registers and stack, and T2 needs a separate set of the same execution state. Switching from T1 to T2 therefore does not create another independent address space.
Place this topic beside DBMS and computer networks in the CS Fundamentals for Exams & Placements subject map.

2. fork() Return Values Build the Process Paths
Apply one rule before doing any multiplication: each successful fork() creates one child from every process path that reaches that call.
If PID 4000 executes child = fork() and the operating system assigns PID 4001 to the child, both processes continue at the next statement. In parent PID 4000, child = 4001. In child PID 4001, child = 0. These return values let later conditions select parent or child paths.
The child has a separate process identity and logically inherited state. An implementation may use copy-on-write to postpone physical copying, but that optimisation does not change the number of processes. Scheduling order is not guaranteed, and the illustrative consecutive PIDs used here should not be treated as a real-world promise.
For safe counting, list the paths currently alive, evaluate the next fork() only on paths that reach it, and add one child for each successful call. Keep two answers separate: total processes, including the original, and newly created children.
3. Fully Worked Example: Trace Conditional fork() Calls
Assume every call succeeds, the illustrative PIDs are assigned as shown, and no output was buffered before the first fork.
a = fork();if (a == 0) { b = fork();}c = fork();printf("X");
Start with P0, PID 4000.
P0 executes
a = fork()and creates C1, PID 4001. There are now 2 processes. P0 hasa = 4001; C1 hasa = 0.Only C1 satisfies
a == 0. Its conditional call creates C2, PID 4002. The running set is now P0, C1 and C2, so the count is 3.All three paths reach
c = fork(). P0 creates C3, PID 4003. C1 creates C4, PID 4004. C2 creates C5, PID 4005. Three existing paths plus three new children give 6 total processes.
The final return values provide a second way to audit the paths:
Final path | PID | Created by final | Value of | Output |
|---|---|---|---|---|
P0 | 4000 | No | 4003 |
|
C1 | 4001 | No | 4004 |
|
C2 | 4002 | No | 4005 |
|
C3 | 4003 | Yes, by P0 | 0 |
|
C4 | 4004 | Yes, by C1 | 0 |
|
C5 | 4005 | Yes, by C2 | 0 |
|
The answer is 6 total processes, 5 newly created children and 6 executions of printf(). The six X characters may appear in any order. A condition on a return value selects paths; an unconditional call doubles only the paths that actually reach it.

4. exec(), wait(), exit() and the Parent-Child Lifecycle
Creation and replacement are different operations. Suppose P0, PID 4000, creates child PID 4001. The child then calls exec("/bin/worker"). Its PID remains 4001, but its old program image is replaced by the worker program. exec() therefore does not add a seventh process to the worked example.
The parent can call waitpid(4001, ...) and block until that child terminates. If PID 4001 exits with illustrative status 7, the parent collects, or reaps, that status and continues.
Two lifecycle terms are worth keeping precise. A zombie is a terminated child whose exit status has not yet been collected. An orphan is a live child whose parent exits first. For exam questions, focus on whether the child is already terminated and whether its parent has collected its status, without assuming platform-specific re-parenting behaviour.
5. Thread Models as a Process-Creation Contrast
Creating T2 inside PID 4000 adds an execution path, not another process or private heap. Threads in one process share code, data or heap, and open files. Each thread keeps a private program counter, register set and stack. Separate processes instead have distinct virtual address spaces and need explicit inter-process communication when they want to exchange data.
Thread models describe how user threads map to kernel scheduling entities:
Many-to-one: several user threads map to one kernel entity. Management can be simpler, but blocking is exposed across the group and parallel kernel scheduling is limited.
One-to-one: each user thread maps to a kernel thread. This supports direct kernel scheduling and concurrency, with more kernel overhead.
Many-to-many: several user threads are multiplexed over a set of kernel threads. The number of user paths can differ from the number of kernel entities, with more complex management.
Shared memory also creates correctness risks. If T1 and T2 both read counter = 12, each computes 13, and each writes 13, the final value can be 13 instead of the intended 14. That lost update follows directly from sharing the heap.
6. How GATE-Style Questions and Interviews Test the Topic
Most questions reduce to five checks:
Count total processes after conditional calls.
Identify the branch that sees a
fork()return value of 0.Distinguish creation by
fork()from image replacement byexec().Classify thread resources as shared or private.
Match many-to-one, one-to-one and many-to-many models to their definitions.
Rapid check 1: if (fork() == 0) printf("C"); else printf("P"); finishes with 2 processes. One prints C and one prints P, in unspecified order.
Rapid check 2: two threads in one process share the heap and open files, while their stacks and registers are private.
7. Short Version and the Next Study Step
fork() creates another process path. Return value 0 identifies the child branch. exec() replaces a process image without creating a process. Threads share process resources but retain separate execution state.
Now redraw the 1 -> 2 -> 3 -> 6 tree from memory, write all six final PIDs, and answer the two rapid checks without notes. For structured GATE preparation, continue with GATE Guidance by Sanchit Sir. If technical interviews are the immediate goal, use CS Fundamentals for Placements by Sanchit Sir to revise the core subjects in that context.
Keep learning

Paging and TLB Explained: Address Translation, EMAT and Exam Traps
Follow one virtual address from its VPN through the TLB to a physical frame, then calculate page-table size, TLB reach and effective memory access time.

Operating System Scenarios: Solve Scheduling, Concurrency, and Page Replacement
Learn one state-trace method for three common OS problem families, then apply it to complete Round Robin, concurrency, FIFO, and LRU examples.

Tower Research Hiring Process: Stage-by-Stage Prep for Quant and Dev Roles
Prepare for a Tower Research application without treating one online account as a universal process. Use this role-led map, worked drills, and seven-day plan.

Capital One Recruitment Process: Stage-by-Stage Guide for India Applicants
Prepare for a Capital One India application with a cautious five-stage map, worked technical and case drills, and a practical 14-hour schedule.