Process Management
Every process on Linux descends from
init. The process tree is the fundamental organizing structure of the OS.
What Is a Process?
A process is an instance of a running program. It has its own virtual address space,
open file descriptors, signal handlers, working directory, and scheduling state.
The kernel represents each process with a task_struct.
fork() — Creating Processes
fork() creates an exact copy of the calling process. The child gets:
- A copy of the parent’s virtual address space (copy-on-write)
- Copies of open file descriptors (pointing to the same underlying files)
- A new PID; the parent’s PID becomes the child’s PPID
pid_t pid = fork();
if (pid == 0) {
// child process
} else if (pid > 0) {
// parent process; pid = child's PID
} else {
// fork failed
}
exec() — Replacing a Process Image
exec replaces the current process’s image with a new program.
The PID stays the same; everything else (address space, open FDs, etc.) is replaced.
fork + exec is the standard pattern for launching new programs.
wait() — Reaping Children
When a child exits, it becomes a zombie — its resources are freed, but its exit
status is held until the parent calls wait() or waitpid(). If the parent never
waits, the zombie lingers until the parent exits (then init adopts and reaps it).
Process Groups and Sessions
Every process belongs to a process group. Process groups belong to sessions. These groupings are used for job control and signal delivery:
SIGINT(Ctrl-C) goes to the entire foreground process groupSIGHUPgoes to all processes in a session when the controlling terminal closes
File Descriptors Across fork
After fork, parent and child share the same underlying open file descriptions
(same offset, same flags). This is how pipes work — you fork, then each side closes
the end it doesn’t need.
Open Questions
- How does
clone()differ fromfork()? (Hint: threads useclonewithCLONE_VM) - What happens to
mmap’d regions acrossfork?