Managing Processes
Every program running on Linux is a process. Each process has a unique Process ID (PID), a parent process, an owner, resource consumption (CPU, memory), and a state. As a sysadmin you need to manage processes: find out what is running and consuming resources, stop misbehaving processes, adjust priorities, and understand the process tree to diagnose problems.
What is a process?
Process lifecycle:
User runs: ./myapp arg1 arg2
↓
Shell calls fork() → creates child PID
↓
Child calls exec() → loads myapp binary into memory
↓
Process runs with:
PID = unique identifier
PPID = parent PID (the shell that launched it)
UID/GID = owner (who owns this process)
State = R(running) / S(sleeping) / Z(zombie) / T(stopped)
↓
Process exits → kernel sends SIGCHLD to parent
↓
Parent calls wait() → zombie entry cleaned from process tableViewing running processes
ps aux # All processes, all users (BSD-style flags)
ps -ef # All processes, full format (POSIX-style flags)
pstree # Visualize parent-child tree
pstree -p # Include PIDs in the tree
ps aux output explained
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 16928 10136 ? Ss 09:00 0:01 /sbin/init
irfan 2341 1.5 2.3 512340 47392 pts/0 Sl 10:30 0:04 /usr/bin/python3 app.py
www-data 3102 0.3 0.8 234512 16384 ? S 10:31 0:01 nginx: worker process
# ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
# user pid cpu mem virtual real tty state time command
top # Interactive real-time process viewer
htop # Better interactive viewer (install: apt install htop)
Process states
| State | Code | Meaning |
|---|---|---|
| Running/Runnable | R | Actively using CPU or waiting in the run queue |
| Interruptible sleep | S | Waiting for I/O or an event — most normal processes |
| Uninterruptible sleep | D | Waiting on I/O that can't be interrupted; too many D = storage problem |
| Zombie | Z | Process exited but parent hasn't called wait(); shouldn't accumulate |
| Stopped | T | Paused by Ctrl+Z or SIGSTOP |
# Find processes in uninterruptible sleep (D state) — storage issues
ps aux | awk '$8 ~ /D/ {print}'
# Count zombie processes
ps aux | awk '$8 ~ /Z/ {print}' | wc -l
Controlling processes
# Signals are the mechanism for controlling processes
kill -l # List all signals
kill PID # Send SIGTERM (15) = polite termination request
kill -9 PID # Send SIGKILL (9) = forced termination, cannot be ignored
kill -STOP PID # Pause a process
kill -CONT PID # Resume a paused process
# By name instead of PID:
pkill nginx # Send SIGTERM to all processes named nginx
pkill -9 -u irfan # Kill all processes owned by user irfan
killall python3 # Kill all python3 processes
⚠️ WARNING:
kill -9(SIGKILL) forces termination without cleanup. The process cannot catch it, flush write buffers, or release locks. Use SIGTERM first, then wait 5 seconds, then use SIGKILL only if the process doesn't exit.
Process ownership and permissions
# Find all processes running as a specific user
ps -u irfan --forest # Processes owned by irfan, with tree view
# Find what process is listening on a port (requires root or sudo)
sudo ss -tlnp | grep :80 # Who is using port 80?
# OR: sudo lsof -i :80 # Alternative command
# Find all open files by a specific process
lsof -p 1234 # All files open by PID 1234
Conclusion
The daily tools: ps aux or htop to see what's running, kill PID (SIGTERM) for normal termination and kill -9 PID (SIGKILL) as a last resort, pstree to understand parent-child relationships. When a process is unresponsive, try SIGTERM first, wait 5-10 seconds, then escalate to SIGKILL. Persistent D-state (uninterruptible sleep) processes indicate a storage or NFS issue — they cannot be killed by any signal while waiting on that I/O.
Need help with Ubuntu administration?
Work directly with Muhammad Irfan Aslam for Ubuntu Server, Linux, cloud, Docker, DevOps, CI/CD, or infrastructure troubleshooting support.
Work with Muhammad Irfan Aslam