What Does the fork() System Call Do?
Learn what fork() does — copy-on-write duplication, return-twice semantics, and parent/child processes — with an OS interview example.
Expected Interview Answer
fork() creates a new process by duplicating the calling process almost exactly, returning twice — once in the parent with the child’s process ID, and once in the child with a return value of 0 — after which the two processes run independently with separate address spaces.
The kernel clones the calling process’s memory image, open file descriptors, and register state into a brand-new process control block, assigning the child a fresh process ID. Modern implementations use copy-on-write: the parent and child initially share the same physical memory pages marked read-only, and a private copy of a page is made only when either process writes to it, which makes fork() cheap even for large address spaces. The single call returns twice because both the parent and child resume execution at the very same point right after the fork() call, distinguished only by the return value — a positive PID in the parent, zero in the child, or a negative value if the fork failed. From that point on, the two processes are independent: they have distinct address spaces, so writes in one are never visible to the other, though open file descriptors initially refer to the same underlying file table entries.
- Creates a new process without re-specifying its entire state from scratch
- Copy-on-write makes duplication cheap until a real write occurs
- Single return-twice semantics let one code path handle both branches
- Foundation for how shells and servers spawn child processes
AI Mentor Explanation
fork() is like a team management office photocopying an entire player’s complete file — form, fitness records, kit assignments — to register a new but nearly identical squad member. Both the original player and the new clone keep training independently afterward, and neither player’s injury report affects the other’s file once they diverge. The copying only actually duplicates a page of the file the moment someone writes new notes on it, rather than photocopying everything upfront, which is why registering a near-identical player is fast.
Step-by-Step Explanation
Step 1
fork() invoked
The calling process traps into the kernel requesting a new process be created.
Step 2
Process duplicated
The kernel creates a new PCB and marks the address space pages copy-on-write, shared with the parent.
Step 3
Two return paths
The kernel schedules both processes; each resumes right after the fork() call in user space.
Step 4
Divergent return values
The parent receives the child PID, the child receives 0, and either can then branch on that value.
What Interviewer Expects
- Explanation of the return-twice semantics and how to distinguish parent from child
- Understanding of copy-on-write as the performance mechanism
- Awareness that address spaces are independent after fork()
- Knowledge that open file descriptors are duplicated (shared file table entries)
Common Mistakes
- Thinking fork() physically copies all memory upfront instead of using copy-on-write
- Confusing the child PID (returned to parent) with 0 (returned to child)
- Assuming the child starts execution at main() again instead of after the fork() call
- Forgetting that fork() can fail and return a negative value if resources are exhausted
Best Answer (HR Friendly)
“fork() is the system call that makes an almost exact copy of the currently running program as a brand-new process. Both the original and the copy keep running from the same point right after the call, but they can tell themselves apart by the return value, and after that they run completely independently of each other.”
Code Example
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void) {
pid_t pid = fork();
if (pid < 0) {
perror("fork failed");
return 1;
} else if (pid == 0) {
printf("child: my pid is %d\n", getpid());
} else {
printf("parent: spawned child pid %d\n", pid);
wait(NULL); /* reap the child to avoid a zombie */
}
return 0;
}Follow-up Questions
- How does copy-on-write make fork() efficient for large processes?
- What happens to open file descriptors after a fork()?
- What is the difference between fork() and vfork()?
- Why is exec() commonly called right after fork()?
MCQ Practice
1. What does fork() return in the child process?
The child process always receives 0 from a successful fork(); the parent receives the child's PID.
2. Why is copy-on-write used with fork()?
Copy-on-write shares pages between parent and child until either writes to one, at which point only that page is duplicated.
3. After fork() returns successfully, the parent and child processes have?
Parent and child get separate address spaces that start out identical but diverge independently once either writes to memory.
Flash Cards
What does fork() do? — Creates a new child process that is a near-duplicate of the calling process, returning twice.
What does fork() return in the parent vs child? — Parent gets the child’s PID; child gets 0.
Why is fork() cheap despite duplicating a whole process? — Copy-on-write defers actually copying memory pages until a write occurs.
Are parent and child address spaces linked after fork()? — No — they are independent; writes in one are never visible to the other.