Process Management:
Find and Control Processes

Identify CPU/memory intensive processes and kill processes

CIS126RH | RHEL System Administration 1
Mesa Community College

When a system slows down unexpectedly, a runaway process is often the cause. Linux administrators must be able to identify which processes are consuming excessive CPU or memory, interpret process state and priority, and terminate or signal processes using the appropriate tools. This module covers the core process monitoring and control commands on RHEL. These skills are tested on the RHCSA exam.

Learning Objectives

  1. List and interpret running processes — Use ps and top to display process information and identify the fields that matter for performance analysis
  2. Identify CPU and memory intensive processes — Sort and filter process listings to find processes consuming the most CPU time or memory
  3. Send signals to processes — Understand the purpose of common signals and use kill, killall, and pkill to control processes
  4. Adjust process scheduling priority — Use nice and renice to raise or lower the CPU scheduling priority of a process

What is a Process?

A process is a running instance of a program. Every process has a unique Process ID (PID) assigned by the kernel when it starts.

Concept Description
PIDProcess ID — unique integer assigned at process creation; PID 1 is systemd
PPIDParent Process ID — the PID of the process that created this one
UID / UserThe user account the process runs as — determines its access permissions
StateCurrent condition of the process (running, sleeping, stopped, zombie)
Priority / NICPU scheduling priority; nice value adjusts it (-20 highest to 19 lowest)
%CPUPercentage of CPU time consumed in the last measurement interval
%MEM / RSSPercentage of RAM used / resident set size in kilobytes
PID 1 is always systemd on RHEL 9

Every other process on the system is a descendant of PID 1. A process tree starting at PID 1 describes the complete running state of the system.

Process States

Every process is in exactly one state at any moment. The state column in ps and top uses single-letter codes.

Code State Meaning
RRunningOn the CPU or ready to run
SSleeping (interruptible)Waiting for an event — can receive signals
DSleeping (uninterruptible)Waiting for I/O — cannot receive signals; cannot be killed
TStoppedSuspended by a signal (e.g. Ctrl+Z) or debugger
ZZombieTerminated but parent has not collected the exit status; no resources held
IIdle kernel threadKernel thread with no work to do
D-state processes cannot be killed

A process in state D (uninterruptible sleep) is waiting for a kernel I/O operation to complete. Signals including SIGKILL are ignored until the I/O completes or times out. This is normal for brief periods; a process stuck in D state for minutes usually indicates a storage or NFS problem.

Listing Processes with ps

ps takes a snapshot of the currently running processes. It is non-interactive — it prints once and exits.

# Most common: show all processes with full info (BSD style)
$ ps aux
USER     PID  %CPU  %MEM    VSZ   RSS TTY  STAT  START   TIME  COMMAND
root       1   0.0   0.1 245260 10240  ?   Ss   07:00   0:02  /usr/lib/systemd/systemd
root     872   0.0   0.2  92548 16384  ?   Ss   07:00   0:00  sshd: /usr/sbin/sshd
student 3421   0.5   0.3  50332 24576  pts/0  S   09:05   0:01  bash

# UNIX style — show all processes with owner and extra info
$ ps -ef
UID    PID  PPID  C  STIME TTY    TIME   CMD
root     1     0  0  07:00  ?   00:00:02  /usr/lib/systemd/systemd

# Show only your own processes
$ ps

# Show processes for a specific user
$ ps -u apache
ps aux vs ps -ef

Both show all processes. ps aux shows %CPU and %MEM columns. ps -ef shows PPID. Both are commonly used — know both formats.

Sorting ps to Find Resource Consumers

Combining ps with sorting options or sort reveals which processes are using the most CPU or memory.

# Sort by CPU usage — highest first
$ ps aux --sort=-%cpu | head -10
USER   PID  %CPU %MEM    VSZ    RSS  CMD
maria  4251  92.3  1.2  58912  98304  /usr/bin/python3 crunch.py
root    872   2.1  0.2  92548  16384  sshd: /usr/sbin/sshd

# Sort by memory usage — highest first
$ ps aux --sort=-%mem | head -10

# Show the top 5 CPU consumers as a one-liner
$ ps aux --sort=-%cpu | awk 'NR<=6'

# Show process tree to see parent-child relationships
$ ps axjf
$ pstree -p
RHCSA Focus

On the exam, if asked to identify the most CPU-intensive process, use ps aux --sort=-%cpu | head or open top and read the top process directly.

Real-Time Monitoring with top

top shows an interactive, live-updating view of system resource usage and the processes consuming the most resources.

# Launch top
$ top

top - 10:45:22 up 14 days, load average: 2.34, 1.87, 1.12
Tasks: 234 total,   3 running, 231 sleeping,   0 stopped,   0 zombie
%Cpu(s): 87.3 us,  3.2 sy,  0.0 ni,  9.1 id,  0.2 wa,  0.0 hi
MiB Mem:   7823.0 total,    412.5 free,   5934.2 used,   1476.3 buff/cache
MiB Swap:  2048.0 total,   1823.0 free,    225.0 used.   1234.5 avail Mem

  PID USER     PR  NI   VIRT   RES   SHR S  %CPU %MEM  TIME+   COMMAND
 4251 maria    20   0  58912  98304 12288 R  92.3  1.2  15:23.45 python3
  872 root     20   0  92548  16384  4096 S   2.1  0.2   0:00.34 sshd
Key top interactive commands

M — sort by memory, P — sort by CPU (default), k — kill a process (prompts for PID and signal), r — renice a process, q — quit, 1 — toggle per-CPU display

Reading the top Output

The top header provides a system-wide health snapshot before the process list.

Field Location What it means
Load averageLine 1Average number of runnable or waiting processes over 1, 5, 15 minutes — should be ≤ CPU count
usCPU lineUser-space CPU — high means busy user processes
syCPU lineKernel-space CPU — high means many system calls
waCPU lineI/O wait — high means storage bottleneck
idCPU lineIdle CPU — 0% means fully utilised
RESProcess listResident set size — physical RAM actually used
VIRTProcess listVirtual memory — includes mapped but not loaded memory
NIProcess listNice value — negative means higher priority

Finding Processes by Name: pgrep

pgrep searches for processes by name or attributes and returns their PIDs — the fastest way to get a PID when you know the process name.

# Get the PID(s) of all httpd processes
$ pgrep httpd
1234
1235
1236

# Show process name alongside PID
$ pgrep -l sshd
872 sshd

# Find processes owned by a specific user
$ pgrep -u apache

# Exact name match — avoids matching partial names
$ pgrep -x bash

# Count matching processes
$ pgrep -c httpd
3

# Get the PID of the most CPU-intensive process for scripting
$ ps aux --sort=-%cpu | awk 'NR==2{print $2}'
4251

Signals: Communicating with Processes

A signal is an asynchronous notification sent to a process. The kernel delivers it; the process handles it, ignores it, or is terminated by it depending on the signal and the process.

Number Name Default action Common use
1SIGHUPTerminateReload configuration — many daemons reload on HUP instead of terminating
2SIGINTTerminateInterrupt — sent by Ctrl+C at the terminal
9SIGKILLTerminate (forced)Unconditional kill — cannot be caught, blocked, or ignored
15SIGTERMTerminateDefault kill — allows the process to clean up; can be caught
18SIGCONTContinueResume a stopped process
19SIGSTOPStopPause a process — cannot be caught or ignored
Most important for the RHCSA exam

Know SIGTERM (15) — the default graceful termination signal, and SIGKILL (9) — the forced kill that cannot be ignored. Always try SIGTERM first; use SIGKILL only when SIGTERM is ineffective.

Sending Signals with kill

kill sends a signal to a process identified by its PID. Despite the name, it can send any signal — not just termination signals.

# Send SIGTERM (15) to a process — the default signal
$ kill 4251

# Send SIGKILL (9) — force kill when SIGTERM is ignored
$ kill -9 4251
$ kill -SIGKILL 4251   # same — name form

# Send SIGHUP (1) to reload a daemon's configuration
$ kill -1 872
$ sudo kill -HUP $(pgrep -x sshd)

# List all available signals
$ kill -l
 1) SIGHUP   2) SIGINT   3) SIGQUIT  9) SIGKILL  15) SIGTERM ...

# Send a signal to multiple PIDs at once
$ kill -15 4251 4252 4253
Always try SIGTERM before SIGKILL

Start with kill PID (SIGTERM). Wait a few seconds. If the process does not exit, use kill -9 PID. Jumping straight to -9 prevents the process from cleaning up and can leave the system in an inconsistent state.

killall and pkill

These commands send signals to processes identified by name rather than PID — useful when a service has multiple worker processes all sharing the same name.

# killall — send a signal to ALL processes with an exact name
$ killall httpd           # SIGTERM to all httpd processes
$ killall -9 httpd        # SIGKILL to all httpd processes
$ sudo killall -HUP sshd  # reload sshd config

# pkill — send a signal to processes matching a pattern
$ pkill httpd             # SIGTERM to all matching httpd
$ pkill -9 httpd          # SIGKILL
$ pkill -u maria          # kill all of maria's processes
$ pkill -u maria bash     # kill maria's bash sessions only
Command Matches by Name matching
kill PIDExact PIDNot applicable
killall nameExact process nameFull name must match
pkill patternProcess name patternPartial match (like grep)

Nice and Renice: Adjusting CPU Priority

The nice value adjusts how much CPU time a process receives relative to other processes. Lower nice = higher priority = more CPU time.

  • Nice values range from -20 (highest priority) to 19 (lowest)
  • Default nice value for new processes is 0
  • Regular users can only increase nice (lower priority)
  • Only root can decrease nice (raise priority) below the current value
# Start a command with a specific nice value
$ nice -n 10 tar -czvf backup.tar.gz /home

# Change the nice value of a running process (PID 4251)
$ renice -n 15 4251
$ renice -n -5 4251    # requires root — raises priority

# Confirm the new nice value in ps output (NI column)
$ ps -o pid,ni,comm -p 4251
  PID  NI COMMAND
 4251  15 python3
Use nice for batch jobs

Starting long-running background tasks with nice -n 10 or higher prevents them from stealing CPU from interactive users and services.

Practical Scenarios

System is slow — find the culprit

$ top               # look at top process — note PID and %CPU
$ ps aux --sort=-%cpu | head -5   # snapshot view

Kill a hung process by name

$ pgrep -l python3    # find the PID
$ kill 4251           # try SIGTERM first
$ kill -9 4251        # force kill if SIGTERM did not work

Run a backup without impacting production

$ nice -n 19 tar -czvf /tmp/backup.tar.gz /var/www/html

Reload a service config without restarting it

$ sudo kill -HUP $(pgrep -x sshd)
# or more clearly:
$ sudo systemctl reload sshd

Process Management Quick Reference

Task Command
List all processes (snapshot)ps aux
Sort by CPU — find top consumersps aux --sort=-%cpu | head -10
Sort by memory — find top consumersps aux --sort=-%mem | head -10
Real-time process monitortop
Get PID by process namepgrep -l processname
Graceful terminate (SIGTERM)kill PID or kill -15 PID
Force kill (SIGKILL)kill -9 PID
Kill all processes with namekillall processname
Kill processes matching patternpkill pattern
Kill all processes for a userpkill -u username
Start with reduced prioritynice -n 10 command
Change running process priorityrenice -n 10 PID
List all signalskill -l
Show process tree with PIDspstree -p

Common Mistakes

Mistake What goes wrong Correct approach
Using kill -9 immediately Process has no chance to clean up — may leave open files, incomplete transactions, or stale locks Try kill PID (SIGTERM) first and wait a few seconds
Trying to kill a D-state process Signal is delivered but the process cannot respond until the I/O completes Investigate the underlying I/O problem; SIGKILL is still ignored in D state
Confusing nice sign direction Higher nice number = lower priority (not higher). Students set nice 10 thinking it raises priority Remember: negative nice = higher priority; positive nice = lower priority
Using pkill with a too-broad pattern Kills more processes than intended — e.g. pkill py may kill all Python processes Use a specific pattern; use pgrep first to confirm what will be matched
Trying to kill another user's process without root Operation not permitted — regular users can only send signals to their own processes Use sudo kill PID for processes owned by another user
Confusing process name for killall vs full command path killall /usr/bin/python3 fails — use the base name only killall python3 — use the short process name, not the full path

Knowledge Check

Answer these before moving to the next slide.

  1. Write the ps command to list all processes sorted by CPU usage with the highest consumer first, showing only the top 5 lines.
  2. What is the difference between SIGTERM and SIGKILL? Which should you try first, and why?
  3. A process named runaway has PID 7823 and is consuming 99% CPU. Write the commands to: (a) send SIGTERM, and (b) force kill it if SIGTERM does not work.
  4. What does a D-state process mean, and why can't you kill it with kill -9?
  5. You want to start a large tar backup job in the background without impacting other users on the system. Write the command.
  6. What is the difference between killall httpd and pkill http?

Knowledge Check — Answers

  1. ps aux --sort=-%cpu | head -6 (6 lines: header + 5 processes)
  2. SIGTERM (15) is the polite termination request — the process can catch it, save state, close connections, and exit cleanly. SIGKILL (9) is unconditional — the kernel immediately removes the process with no cleanup. Always try SIGTERM first because a clean exit prevents data corruption, stale locks, and incomplete transactions.
  3. (a) kill 7823 (SIGTERM — the default).
    (b) kill -9 7823 if the process does not exit after a few seconds.
  4. A D-state (uninterruptible sleep) process is waiting for a kernel I/O operation to complete — typically disk, NFS, or other hardware I/O. Signals are queued but not delivered while the process is in D state. Even SIGKILL cannot force the process out of D state — only the completion or timeout of the I/O operation does. A long-running D state usually indicates a storage problem.
  5. nice -n 19 tar -czvf /tmp/backup.tar.gz /home & — nice value 19 gives the lowest CPU priority; the & runs it in the background.
  6. killall httpd sends SIGTERM to processes whose name is exactly httpd. pkill http sends SIGTERM to all processes whose name contains http — which could include httpd, httpd-worker, and others. killall is more precise; pkill is broader.

Key Takeaways

  1. Use top for live monitoring; ps aux --sort=-%cpu for snapshots. The most CPU-intensive process is at the top of the list in both tools. The %CPU and %MEM columns identify resource consumers. Note the PID for subsequent signal commands.
  2. Always try SIGTERM before SIGKILL. kill PID sends SIGTERM (graceful). kill -9 PID sends SIGKILL (forced). SIGTERM allows cleanup; SIGKILL does not. Processes in D state cannot be killed by any signal — investigate the underlying I/O problem.
  3. Use the right tool for the target. kill by PID when you have the exact process. killall by exact name when killing all instances of a program. pkill by pattern when more flexibility is needed. Run pgrep first to confirm what will be matched.
  4. Nice controls CPU scheduling priority. Lower nice value = higher priority = more CPU time. Start low-priority jobs with nice -n 10 or higher. Adjust running processes with renice -n VALUE PID. Only root can decrease nice (raise priority).

Graded Lab

  • Run top and identify the three highest CPU-consuming processes. Note each PID, process name, and %CPU value. Press q to exit.
  • Run ps aux --sort=-%mem | head -6 to find the three processes using the most memory. Compare them to the top CPU consumers.
  • Start a background process: sleep 600 &. Use pgrep -l sleep to find its PID. Send it SIGTERM with kill and confirm it is gone with pgrep sleep.
  • Start another background process: sleep 600 &. This time use kill -9 to force kill it. Verify it no longer appears in ps aux output.
  • Start a sleep 600 process with nice value 15: nice -n 15 sleep 600 &. Confirm the NI column shows 15 in ps -o pid,ni,comm -p $(pgrep sleep). Use renice -n 5 to change its priority. Verify. Kill it when done.
  • Use killall sleep to terminate all remaining sleep processes at once. Confirm with pgrep sleep.
RHCSA Objective

"Identify CPU/memory intensive processes and kill processes." Know top, ps aux, kill, killall, and pkill. Always try SIGTERM before SIGKILL.