Every program running on Linux is a process: the browser, the shell you type into, the web server, even the ls command for the fraction of a second it works. Knowing how to observe processes and step in when something hangs or eats too many resources is one of the most useful skills for anyone running a system, even just their own laptop.
PID, parent process and the process tree
Every process has an identification number, the PID, and a parent process that created it, identified by the PPID. When you launch firefox from a terminal, the shell is Firefox's parent. Climbing up the tree you reach the process with PID 1, which on modern distributions is almost always systemd: it is the first process started by the kernel and the ancestor of all the others.
The pstree command draws this tree and shows who started what.
Listing processes with ps
ps on its own shows only the processes of the current terminal. The most common variants are:
ps aux: all processes of all users, with CPU and memory usage;ps -ef: the same list in a different format, with the PPID shown;ps aux --sort=-%mem | head: the processes using the most memory.
To look for a specific program you combine it with grep, or use pgrep -a name directly, which returns PID and command line without including itself in the results.
Watching in real time: top and htop
top shows a list refreshed every few seconds. At the top are the load average over 1, 5 and 15 minutes, CPU usage and memory usage. Some useful keys inside top:
| Key | Action |
|---|---|
P |
sort by CPU usage |
M |
sort by memory usage |
k |
send a signal to a process |
1 |
show each core separately |
q |
quit |
htop, often installed separately, offers the same information with colours, a bar for each core and the ability to scroll and select processes with the arrow keys.
The load average must be read relative to the number of cores: a value of 4 on a 4-core machine means a fully busy system, on a 16-core machine a quiet one.
Process states
The STAT column of ps or S in top shows a letter:
Rrunning or ready to run;Swaiting for an event, the most common state;Duninterruptible wait, usually on disk or network;Tstopped, for example withCtrl+Z;Zzombie: finished, but its parent has not yet collected its exit status.
Many processes in state D often point to a slow disk or a network drive that is not responding. Zombies use no CPU or significant memory; if they pile up, the problem is the parent process that does not reap them.
Signals: asking and forcing a process to stop
The kill command is not only for killing: it sends a signal to a process. The most important are:
- SIGTERM (15): the polite request to terminate. It is
kill's default signal. The program can catch it, save its data and shut down cleanly. - SIGKILL (9): forced termination. The kernel ends the process immediately, without giving it a chance to react. Unsaved data is lost.
- SIGHUP (1): historically the closing of the terminal; many services use it as a command to reload their configuration.
- SIGINT (2): what you send by pressing
Ctrl+C. - SIGSTOP and SIGCONT: pause and resume a process.
The practical rule is to always try SIGTERM first and move to SIGKILL only if the process is still there after a few seconds:
kill 4321 # SIGTERM
sleep 5
kill -9 4321 # only if needed
pkill name and killall name send the signal by name instead of PID; it is wise to check first with pgrep -a name which processes will be hit. A process in state D may not respond even to SIGKILL until the operation it is stuck on completes.
Priority: nice and renice
Linux shares the CPU among processes partly based on the nice value, which ranges from -20 (highest priority) to 19 (lowest). A heavy but non-urgent task, such as compressing an archive, can be started with low priority:
nice -n 15 tar -czf archive.tar.gz folder/
For a process that is already running you use renice. Normal users can only lower the priority of their own processes; raising it requires administrator privileges.
Foreground and background jobs
In the shell, adding & at the end of a command starts it in the background. Ctrl+Z suspends the foreground command, bg resumes it in the background, fg brings it back to the foreground and jobs lists the session's jobs. If you close the terminal, however, the jobs receive SIGHUP and normally terminate: for long operations on a server it is better to use nohup, or a multiplexer such as tmux or screen, which keeps the session alive even if the connection drops.
In short
- Every process has a PID and a parent;
pstreeshows who started what. ps aux,topandhtopshow CPU and memory use; compare the load with the number of cores.- Use SIGTERM first and only then SIGKILL, which gives the program no time to save.
niceandrenicelower the priority of heavy but non-urgent jobs.- For long remote jobs use
tmuxorscreen, not a plain&.