Linux Process Management: ps, top, and kill Aren't Enough
You’ve definitely run ps aux | grep something and called it a day. But Linux process management is way more powerful than the basics. Let’s dig into what’s really happening.
What Even Is a Process?
A process is just a running program. When you execute a binary, the kernel:
- Allocates memory
- Assigns a PID (Process ID)
- Sets up file descriptors (stdin, stdout, stderr)
- Starts executing instructions
Every process has a parent (except PID 1, which is init/systemd). Check the process tree:
pstree -p
Process States
Processes aren’t just “running” or “stopped”. They go through multiple states:
- R (Running): Currently executing or ready to run
- S (Sleeping): Waiting for an event (I/O, user input, etc.)
- D (Uninterruptible Sleep): Waiting for disk I/O (can’t be killed!)
- Z (Zombie): Finished executing but parent hasn’t read exit status
- T (Stopped): Paused by a signal (Ctrl+Z)
See state of all processes:
ps aux
# S column shows state
Signals: How Processes Communicate
When you run kill, you’re sending a signal. SIGKILL (-9) isn’t the only option:
# Politely ask process to terminate
kill -TERM <PID> # or kill -15 <PID>
# Force immediate termination (no cleanup!)
kill -KILL <PID> # or kill -9 <PID>
# Pause process
kill -STOP <PID> # Ctrl+Z does this
# Resume process
kill -CONT <PID> # fg does this
# Reload config without restart
kill -HUP <PID> # Many daemons support this
Use kill -l to see all available signals.
The Problem with kill -9
Everyone defaults to kill -9 but it’s dangerous. The process gets no chance to:
- Close files properly
- Flush buffers
- Clean up child processes
- Remove lock files
Always try kill -TERM first. Give it 5 seconds. Only then resort to -9.
Finding Resource Hogs
top is fine but htop is better. Install it:
sudo apt install htop # Ubuntu/Debian
sudo yum install htop # RHEL/CentOS
Better yet, use ps with custom formatting:
# Top 10 CPU consumers
ps aux --sort=-%cpu | head -11
# Top 10 memory consumers
ps aux --sort=-%mem | head -11
# Specific process CPU/memory
ps -p <PID> -o %cpu,%mem,cmd
Background Jobs and Disown
Start a long-running process in the background:
./long_running_script.sh &
But if you log out, it dies. Use nohup:
nohup ./long_running_script.sh &
# Output goes to nohup.out
Or disown to detach an already running job:
./long_running_script.sh &
disown
Even better, use screen or tmux for persistent sessions.
systemd: Modern Process Management
For production services, systemd is the way. Create a unit file:
[Unit]
Description=My Web App
After=network.target
[Service]
Type=simple
User=webuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/server
Restart=always
[Install]
WantedBy=multi-user.target
Save to /etc/systemd/system/myapp.service and:
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp # Start on boot
sudo systemctl status myapp # Check status
systemd handles restart on failure, logging, and dependencies automatically.
Debugging Stuck Processes
Process stuck in D state (uninterruptible sleep)? It’s waiting on I/O. Check what it’s doing:
# See what files it has open
lsof -p <PID>
# See system calls it's making
strace -p <PID>
# Check I/O wait
iostat -x 1
Zombie Processes
Zombies happen when a child process finishes but the parent hasn’t called wait(). They’re harmless (use zero resources) but if you have thousands, something’s wrong with the parent.
Find zombie parents:
ps aux | awk '$8=="Z" {print $2}' | xargs -I {} ps -o ppid= -p {}
Then fix or restart the parent process.
Understanding process management makes debugging production issues way easier. Most problems come down to signals, states, or resource contention - and now you know how to diagnose all three.