Process tree

Also known as: pstree

On this page 7

A process tree is the hierarchy formed by running processes and their parent-child relationships on a Linux system. Every process except the first is created by another process, its parent, so all processes together form a tree rooted in PID 1, which on most modern distributions is systemd.

In the context of Linux processes, the tree explains who started what, which process collects a child’s exit status, and how signals, sessions and terminals propagate. The tree is commonly inspected with the pstree command, whose name is often used as a synonym, and with ps –forest or the tree view of interactive monitors.

How the process tree is built

The tree grows through the fork() and clone() system calls. When a process forks, the kernel creates a near-identical copy with a new process ID (PID) and records the creator’s PID as the child’s parent process ID (PPID). The child often calls execve() next to replace its program, but the parent-child link remains.

At boot, the kernel starts two special processes. PID 1, the init system, becomes the ancestor of all user-space processes, and PID 2, kthreadd, becomes the parent of kernel threads, which pstree and ps display in brackets. A typical interactive shell therefore sits several levels below PID 1: systemd, a login or terminal manager, the terminal emulator or SSH daemon, and finally the shell.

IdentifierMeaningWhere to see it
PIDUnique ID of the processps, /proc/PID
PPIDPID of the parentps -o ppid, PPid in /proc/PID/status
PGIDProcess group, used for job controlps -o pgid
SIDSession, usually tied to a terminalps -o sid
TTYControlling terminal of the sessionps -o tty
Key identifiers that describe a position in the process tree

Viewing the process tree

Several standard tools draw the tree, each with a different balance of compactness and detail. Choosing the right one depends on whether the goal is a quick overview or a precise diagnosis.

CommandOutput styleUseful options
pstreeCompact ASCII tree, identical children merged-p for PIDs, -a for arguments, -u for user changes
ps -ef –forestFull process list with tree indentationCombine with grep for a subtree
ps axjfTree with PPID, PGID and SID columnsGood for session analysis
htop or topInteractive tree viewTree mode key in htop, V in top
systemd-cglsTree of control groups, not parentsShows services and their processes
Tools for inspecting the process tree

By default, pstree collapses identical sibling processes into a notation such as 4 times a worker name in square brackets, which keeps large trees readable. Running pstree -p PID shows only one subtree with PIDs, which is the fastest way to see everything a service or shell has spawned.

Orphans, zombies and reparenting

The tree changes when processes end, and two states explain most surprises. A zombie process has exited, but its parent has not yet collected its exit status with wait(); it keeps only a process table entry. An orphan is a running process whose parent has already exited.

SituationWhat the kernel doesVisible symptom
Child exits, parent aliveKeeps a zombie until the parent waitsState Z, marked as defunct
Parent exits firstReparents the child to a subreaper or PID 1PPID changes to 1 or the subreaper
Orphaned zombieNew parent reaps itZombie disappears
Parent never waitsZombies accumulateGrowing count of defunct entries
Process states caused by tree relationships

A process can declare itself a child subreaper with the prctl option PR_SET_CHILD_SUBREAPER, so orphaned descendants are reparented to it instead of PID 1. Service managers and container runtimes use this to keep track of every descendant, even those that detached by double forking.

Process tree compared with groups, sessions and cgroups

The process tree records ancestry only. Other kernel structures group processes for different purposes, and confusing them with the tree leads to incomplete cleanup and misdirected signals.

  • Process groups collect the processes of one shell pipeline, so job control can stop or resume them together and kill with a negative PID can signal the whole group.
  • Sessions collect process groups attached to one terminal; closing the terminal sends SIGHUP to the session, unless a process was started with nohup or detached.
  • Control groups (cgroups) track resource usage and limits; a process stays in its cgroup even after it is reparented, which is why systemd uses cgroups rather than the tree to stop services reliably.
  • PID namespaces give containers their own tree, in which the container’s first process appears as PID 1 and must reap orphans.

The last point is a frequent container problem: an application that runs as PID 1 in a container without reaping children accumulates zombies. A minimal init process placed at the top of the container’s tree solves it.

Using the tree for diagnosis and control

Administrators read the process tree to answer practical questions: which service launched an unexpected process, why a command keeps running after logout, or which parent is failing to reap zombies. The parent of a zombie is the process to fix or restart, because a zombie itself cannot be killed.

Killing a parent does not automatically kill its children; they are reparented and keep running. To stop a whole subtree, signal the process group, stop the systemd unit, or use pkill -P PPID for direct children. In security investigations, an unusual ancestry, such as a web server spawning a shell, is a classic sign of compromise.

Put simply

A process tree is a family tree of running programs. Every program on the computer was started by another program, its parent, and the very first one is started by the system itself when the computer boots.

Looking at this family tree shows where each program came from. If a parent leaves, its children are adopted by the system’s first program, so nothing is left without a parent that can tidy up after it.

In practice

On a Linux web server, monitoring reports that the number of processes has grown to several thousand over two days. Running ps shows hundreds of entries marked as defunct. The administrator runs pstree -p on the application’s main PID and sees that all the zombies are children of one worker process of a custom job scheduler.

The scheduler launches a small script for every task but never calls wait() on finished children. Restarting the scheduler makes the zombies orphans, PID 1 reaps them, and the process count drops at once. The development team then fixes the code to reap children properly, and the administrator adds an alert on the zombie count so the problem cannot silently return.