Skip to content

Process Lifecycle in Linux

First PublishedByAtif Alam

A process is created by fork (or clone()), often runs a new program via exec, and eventually exits. The kernel sends SIGCHLD to the parent when a child terminates; the parent should wait() (or waitpid()) to reap the child. If the parent does not reap, the child remains a zombie until the parent does so or the parent exits (then init adopts and reaps). You cannot kill a zombie — it is already dead; only the parent (or init) can clear it by waiting. See Signals for SIGCHLD and signal handling.

  • fork() — Creates a child process as a copy of the parent (copy-on-write for memory). Returns twice: PID of child in parent, 0 in child. The child gets a new PID.
  • exec() — Replaces the current process’s program (code, data, heap, stack) with a new executable. File descriptors (unless marked close-on-exec), PID, and parent do not change. Often used in the child after fork (fork + exec is how shells run commands).
  • exit() — Process terminates; kernel keeps a small record (PID, exit status) until the parent calls wait() or waitpid(). Until then the process is in the zombie state.

A zombie (state Z or <defunct> in ps) is a process that has exited but has not been reaped by its parent. The kernel keeps the PID and exit status so the parent can retrieve them with wait().

The process is already dead — it has no code running. SIGKILL and SIGTERM have no effect. The only way to remove a zombie is for the parent to call wait() or waitpid(). If the parent is stuck or does not implement waiting:

  • Restart or kill the parent — When the parent exits, the kernel reparents the zombie to init (PID 1); init reaps all children, so the zombie disappears.
  • SIGCHLD handler — If you control the parent, install a handler for SIGCHLD that calls waitpid(-1, &status, WNOHANG) to reap children as they exit and avoid zombies.

If the parent exits before the child, the child becomes an orphan. The kernel reparents it to init (PID 1). Init will reap it when it exits, so orphans do not become permanent zombies.

ToolPurpose
ps, top, htopList processes; zombies show as Z or defunct.
strace -fTrace fork, exec, exit.
pstreeParent–child tree.
/proc/<pid>/statusState (e.g. Zombie).
wait/waitpidIn code: reap children.
killSend signal to parent (to force reap by killing parent).
gdb, dmesgDebug crashes; kernel messages.
  • Parent–child treepstree -p shows PIDs and hierarchy.
  • Trace fork/exec/exitstrace -f -e fork,execve,exit_group ./program or attach to a running process.
  • Find zombiesps aux | grep Z or ps -eo pid,state,comm | grep Z. Check parent with ps -o ppid= -p <zombie_pid>.
  • Process statecat /proc/<pid>/status; State: shows running, zombie, etc.
  • Reaping in C — In the parent, call waitpid(-1, &status, WNOHANG) in a loop or in a SIGCHLD handler to collect exit status and clear zombies.
Parent
|
| fork()
v
Child
|
| exec(new_program)
v
Running (new program)
|
| exit(status)
v
Zombie (defunct) ----[ parent wait() ]----> Reaped (gone)
|
| If parent dies: reparent to init; init wait() reaps
v
Reaped

Parent → fork → Child → exec → run → exit → zombie; parent wait() reaps. If parent dies first, init reaps the zombie.