What Does the wait() System Call Do?
Learn what wait() does — reaping child exit status, zombie processes, and waitpid() — with a worked OS interview example.
Expected Interview Answer
wait() suspends the calling parent process until one of its child processes terminates, then reaps that child’s exit status and releases the kernel resources still held by the finished child, preventing it from lingering as a zombie.
When a process terminates, the kernel does not immediately discard it: it keeps the exit status and basic accounting information around in a zombie state until the parent retrieves that information, because the parent may need to know how the child exited. Calling wait() (or the more flexible waitpid(), which can target a specific child PID and be made non-blocking) blocks the parent until any child exits, then returns that child’s PID and its exit status, at which point the kernel frees the zombie’s remaining PCB. If a parent never calls wait() and exits itself, its zombie children are reparented to the init process (or a subreaper), which periodically reaps them so they don’t accumulate forever. Failing to reap children in a long-running parent, such as a server that forks workers, causes zombie processes to pile up and can exhaust the system’s process table.
- Lets a parent retrieve a child's exit status and know how it terminated
- Prevents zombie processes from accumulating and exhausting the process table
- waitpid() allows targeting a specific child or non-blocking polling
- Essential for correct process supervision in servers and shells
AI Mentor Explanation
wait() is like a team manager who must formally sign off on a departing player’s final match report before that player’s slot on the roster is freed up — until the manager reviews it, the player’s name stays listed even though they’ve already left the field, occupying a roster spot. Calling wait() is the manager finally reading the report, recording how the player performed, and freeing that roster slot for someone new. A manager who never reviews departing reports ends up with a roster clogged with names of players who already left.
Step-by-Step Explanation
Step 1
Child terminates
A child process exits, but the kernel keeps its exit status and PCB remnants as a zombie entry.
Step 2
Parent calls wait()
The parent invokes wait() or waitpid(), blocking if no child has exited yet.
Step 3
Kernel returns status
Once a child is a zombie, wait() returns its PID and exit status to the parent.
Step 4
Zombie reaped
The kernel releases the remaining PCB resources for that child, fully removing it from the process table.
What Interviewer Expects
- Understanding that wait() blocks until a child terminates and reaps its exit status
- Knowledge of what a zombie process is and why it exists
- Awareness of waitpid() for targeting a specific PID or non-blocking checks
- Understanding of reparenting to init/subreaper when a parent exits without waiting
Common Mistakes
- Confusing a zombie process with an orphan process
- Thinking a child process disappears immediately on exit without being reaped
- Forgetting that failing to call wait() in a long-running parent leaks zombie entries
- Not knowing waitpid() can target a specific child or be made non-blocking with WNOHANG
Best Answer (HR Friendly)
“wait() is the call a parent process uses to pause and find out when one of its child processes has finished, and to collect that child’s exit status. It’s also how the operating system cleans up after a finished child — without it, the child would linger around as a zombie entry taking up a slot in the process table.”
Code Example
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void) {
pid_t pid = fork();
if (pid == 0) {
_exit(42); /* child exits with status 42 */
} else if (pid > 0) {
int status;
pid_t reaped = wait(&status); /* blocks until the child exits */
if (WIFEXITED(status)) {
printf("child %d exited with code %d\n",
reaped, WEXITSTATUS(status));
}
}
return 0;
}Follow-up Questions
- What is a zombie process and how does wait() prevent it from persisting?
- What is the difference between wait() and waitpid()?
- What happens to a child's zombie entry if the parent never calls wait()?
- How does WNOHANG change waitpid()'s blocking behavior?
MCQ Practice
1. What does wait() primarily do?
wait() blocks the calling parent until one of its children exits, then returns that child’s PID and exit status.
2. A zombie process exists because?
A terminated child stays as a zombie, holding its exit status in the process table, until the parent calls wait() to retrieve it.
3. If a parent process exits without ever calling wait() on its children, what happens?
Orphaned children are reparented to init or a subreaper, which periodically calls wait() to reap them.
Flash Cards
What does wait() do? — Blocks the parent until a child exits, then returns that child’s PID and exit status.
What is a zombie process? — A terminated child whose exit status hasn’t been reaped by its parent yet.
How do you wait for a specific child? — Use waitpid() with that child's PID instead of wait().
What happens if a parent never calls wait()? — Its zombie children accumulate until it exits, after which they are reparented to init for reaping.