RED HAT ENTERPRISE LINUX

Process Management

Investigate, Control, and Terminate Processes

College-Level Course Module | RHEL System Administration

Learning Objectives

1
Understand processes

Process concepts, states, and the process hierarchy

2
Investigate processes

Use ps, top, and other tools to view process information

3
Control job execution

Manage foreground and background processes

4
Send signals to processes

Use kill and related commands to control processes

5
Adjust process priority

Use nice and renice to manage CPU scheduling

What is a Process?

A process is a running instance of a program. When you execute a command, the kernel creates a process, assigns it resources, and schedules it for execution.

Process Attributes:
  • PID - Unique Process ID
  • PPID - Parent Process ID
  • UID/GID - User/Group ownership
  • Priority - Scheduling priority
  • State - Current execution state
  • Memory - Allocated memory space
Program vs Process:
  • Program - Executable file on disk
  • Process - Running program in memory
  • One program can spawn many processes
  • Each process has isolated memory
  • Processes share CPU time
# Every process has a unique PID
[user@host ~]$ echo $$
1234            # Current shell's PID

Process States

Processes move between states as they execute. Understanding states helps diagnose process behavior.

StateCodeDescription
Running R Currently executing on CPU or waiting in run queue
Sleeping (Interruptible) S Waiting for event (I/O, signal) - can be interrupted
Sleeping (Uninterruptible) D Waiting for I/O - cannot be interrupted (disk wait)
Stopped T Suspended by signal (Ctrl+Z) or debugger
Zombie Z Terminated but parent hasn't read exit status
Created
Ready
Running
Terminated

Process Hierarchy

Processes form a parent-child hierarchy. Every process (except PID 1) has a parent. When processes create new processes, they become children.

# View process tree
[user@host ~]$ pstree
systemd─┬─NetworkManager───3*[{NetworkManager}]
        ├─agetty
        ├─auditd───{auditd}
        ├─crond
        ├─sshd───sshd───sshd───bash───pstree
        └─systemd-journal

# Show PIDs in tree
[user@host ~]$ pstree -p
systemd(1)─┬─sshd(1234)───sshd(5678)───sshd(5680)───bash(5681)───pstree(5700)

# Show tree for specific process
[user@host ~]$ pstree -p 1234
PID 1 (systemd): The first process started at boot. It is the ancestor of all other processes and adopts orphaned processes.

Viewing Processes: ps

ps (process status) displays a snapshot of current processes. Different options show different information.

# Basic ps - shows processes in current terminal
[user@host ~]$ ps
  PID TTY          TIME CMD
 5681 pts/0    00:00:00 bash
 5700 pts/0    00:00:00 ps

# Show all processes (BSD style - most common)
[user@host ~]$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY   STAT START   TIME COMMAND
root         1  0.0  0.3 171820 13256 ?     Ss   09:00   0:02 /usr/lib/systemd/systemd
root         2  0.0  0.0      0     0 ?     S    09:00   0:00 [kthreadd]
apache    1234  0.2  1.5 550000 62000 ?     S    09:15   0:45 /usr/sbin/httpd
student   5681  0.0  0.1  27000  4500 pts/0 Ss   10:30   0:00 -bash

# Show all processes (Unix style)
[user@host ~]$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:00 ?        00:00:02 /usr/lib/systemd/systemd
student   5681  5680  0 10:30 pts/0    00:00:00 -bash

Understanding ps Output

ColumnDescriptionExample
USERProcess ownerroot, apache, student
PIDProcess ID1, 1234, 5681
%CPUCPU usage percentage0.0, 25.5, 99.9
%MEMMemory usage percentage0.1, 5.2, 15.0
VSZVirtual memory size (KB)Total addressable memory
RSSResident Set Size (KB)Actual physical RAM used
TTYControlling terminalpts/0, tty1, ? (none)
STATProcess stateS, R, D, T, Z (+ modifiers)
STARTWhen process started09:00, Jan15
TIMECumulative CPU time0:00, 5:32
COMMANDCommand that started process/usr/sbin/httpd
# STAT column modifiers:
s - session leader      l - multi-threaded
+ - foreground process  < - high priority
N - low priority        L - pages locked in memory

Filtering ps Output

# Find processes by name using grep
[user@host ~]$ ps aux | grep httpd
root      1234  0.0  0.5 275000 20000 ?  Ss  09:15  0:00 /usr/sbin/httpd
apache    1235  0.0  0.3 275500 12000 ?  S   09:15  0:01 /usr/sbin/httpd
apache    1236  0.0  0.3 275500 12000 ?  S   09:15  0:01 /usr/sbin/httpd
student   5720  0.0  0.0  12000  1000 pts/0 S+ 10:45 0:00 grep httpd

# Exclude grep from results
[user@host ~]$ ps aux | grep [h]ttpd
[user@host ~]$ ps aux | grep httpd | grep -v grep

# Find processes by user
[user@host ~]$ ps -u apache
[user@host ~]$ ps aux | grep ^apache

# Find process by PID
[user@host ~]$ ps -p 1234

# Custom output format
[user@host ~]$ ps -eo pid,user,%cpu,%mem,cmd --sort=-%cpu | head
  PID USER     %CPU %MEM CMD
 3456 mysql    45.2 12.5 /usr/libexec/mysqld
 1234 apache    8.3  2.1 /usr/sbin/httpd

Real-time Monitoring: top

top provides a dynamic, real-time view of processes. It updates continuously and allows interactive sorting and filtering.

[user@host ~]$ top
top - 10:45:23 up 1 day,  2:30,  2 users,  load average: 0.15, 0.10, 0.05
Tasks: 156 total,   1 running, 155 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.3 us,  1.0 sy,  0.0 ni, 96.5 id,  0.1 wa,  0.0 hi,  0.1 si
MiB Mem :   3936.0 total,   1524.0 free,   1200.0 used,   1212.0 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.   2500.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 3456 mysql     20   0 1256000 512000  15000 S  12.3  12.7   5:23.45 mysqld
 1234 apache    20   0  275000  62000  12000 S   2.5   1.5   0:45.12 httpd
    1 root      20   0  171820  13256   8500 S   0.0   0.3   0:02.35 systemd
Key metrics in header: Load average (1, 5, 15 min), CPU breakdown (user, system, idle, wait), Memory usage

Interactive top Commands

KeyActionKeyAction
h or ?Help screenqQuit top
MSort by memoryPSort by CPU (default)
NSort by PIDTSort by time
uFilter by usercToggle full command
kKill a processrRenice a process
1Toggle per-CPU statsmToggle memory display
SpaceRefresh immediatelydChange refresh delay
# Start top sorted by memory
[user@host ~]$ top -o %MEM

# Show only specific user's processes
[user@host ~]$ top -u apache

# Batch mode (for scripting, non-interactive)
[user@host ~]$ top -bn1 | head -20

# Set refresh interval to 1 second
[user@host ~]$ top -d 1

Other Monitoring Tools

# htop - enhanced interactive process viewer (if installed)
[user@host ~]$ htop
# Better visual interface, mouse support, easier to use

# pidof - find PID by process name
[user@host ~]$ pidof httpd
1236 1235 1234

# pgrep - search processes by pattern
[user@host ~]$ pgrep -l http
1234 httpd
1235 httpd

# pgrep with more details
[user@host ~]$ pgrep -a httpd
1234 /usr/sbin/httpd -DFOREGROUND

# lsof - list open files by process
[user@host ~]$ lsof -p 1234 | head

# What process is using a file?
[user@host ~]$ lsof /var/log/messages

# What process is using a port?
[user@host ~]$ lsof -i :80

Foreground and Background

Foreground processes receive keyboard input and block the terminal. Background processes run without blocking, freeing the terminal for other work.

# Run command in foreground (default)
[user@host ~]$ sleep 60
# Terminal is blocked for 60 seconds...

# Run command in background (add &)
[user@host ~]$ sleep 60 &
[1] 5800      # [job number] PID
[user@host ~]$ # Terminal available immediately

# Suspend foreground process (Ctrl+Z)
[user@host ~]$ sleep 60
^Z
[1]+  Stopped                 sleep 60

# Resume in background
[user@host ~]$ bg
[1]+ sleep 60 &

# Bring to foreground
[user@host ~]$ fg
sleep 60

Managing Jobs

# List current jobs
[user@host ~]$ jobs
[1]-  Running                 sleep 100 &
[2]+  Stopped                 vim file.txt

# Jobs with PIDs
[user@host ~]$ jobs -l
[1]-  5800 Running                 sleep 100 &
[2]+  5810 Stopped                 vim file.txt

# Bring specific job to foreground
[user@host ~]$ fg %1           # Job number 1
[user@host ~]$ fg %vim         # Job starting with "vim"

# Resume specific job in background
[user@host ~]$ bg %2

# The + and - indicate:
# + current job (default for fg/bg)
# - previous job

# Disown - remove job from shell's job table
[user@host ~]$ disown %1
# Process continues but shell doesn't track it

Keeping Processes Running

Normally, background processes terminate when you log out. Use nohup to keep them running.

# nohup - "no hangup" - ignore SIGHUP signal
[user@host ~]$ nohup long-running-script.sh &
nohup: ignoring input and appending output to 'nohup.out'
[1] 5850

# Output goes to nohup.out (or redirect explicitly)
[user@host ~]$ nohup ./backup.sh > backup.log 2>&1 &

# Now safe to log out - process continues
[user@host ~]$ exit

# Later, check if still running
[user@host ~]$ ps aux | grep backup

# Alternative: screen or tmux for interactive sessions
[user@host ~]$ screen -S mysession
# Work in screen session...
# Detach with Ctrl+A, D
# Reattach later:
[user@host ~]$ screen -r mysession

Understanding Signals

Signals are software interrupts sent to processes. They notify processes of events and can request termination, reload, or other actions.

SignalNumberDefault ActionDescription
SIGHUP1TerminateHangup - terminal closed, often used to reload config
SIGINT2TerminateInterrupt - Ctrl+C pressed
SIGQUIT3Core dumpQuit - Ctrl+\ pressed
SIGKILL9TerminateKill - cannot be caught or ignored, immediate death
SIGTERM15TerminateTerminate - polite request to exit (default for kill)
SIGSTOP19StopStop - cannot be caught, pauses process
SIGCONT18ContinueContinue - resume stopped process
SIGTSTP20StopTerminal stop - Ctrl+Z pressed
Key distinction: SIGTERM asks nicely (process can clean up). SIGKILL forces immediately (no cleanup possible).

Sending Signals: kill

kill sends signals to processes. Despite the name, it can send any signal, not just termination signals.

# Default: send SIGTERM (signal 15)
[root@host ~]# kill 1234

# Specify signal by name
[root@host ~]# kill -SIGTERM 1234
[root@host ~]# kill -TERM 1234

# Specify signal by number
[root@host ~]# kill -15 1234

# Force kill (cannot be caught - use as last resort)
[root@host ~]# kill -9 1234
[root@host ~]# kill -SIGKILL 1234

# Send to multiple processes
[root@host ~]# kill 1234 1235 1236

# List available signals
[user@host ~]$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 9) SIGKILL     15) SIGTERM     18) SIGCONT     19) SIGSTOP ...
Best practice: Try SIGTERM first. Only use SIGKILL (-9) if SIGTERM fails after a few seconds.

killall and pkill

# killall - kill by exact process name
[root@host ~]# killall httpd
# Sends SIGTERM to all processes named exactly "httpd"

# killall with specific signal
[root@host ~]# killall -9 httpd
[root@host ~]# killall -SIGHUP httpd     # Reload config

# pkill - kill by pattern (more flexible)
[root@host ~]# pkill http
# Matches any process containing "http"

# pkill by user
[root@host ~]# pkill -u student
# Kill all processes owned by student

# pkill with signal
[root@host ~]# pkill -9 -u baduser

# Preview what would be killed (like pgrep)
[user@host ~]$ pgrep -l http
1234 httpd
1235 httpd
# Then: pkill http
Caution: pkill matches patterns - pkill user might kill more than intended. Preview with pgrep first!

Process Priority

The Linux scheduler uses nice values to determine CPU priority. Lower nice values = higher priority. Range: -20 (highest) to 19 (lowest).

-20
Highest
-10
0
Default
+10
+19
Lowest
# View process nice values (NI column)
[user@host ~]$ ps -eo pid,ni,cmd
  PID  NI CMD
    1   0 /usr/lib/systemd/systemd
 1234   0 /usr/sbin/httpd
 5000  10 /usr/local/bin/backup.sh

# Also visible in top (NI column)
[user@host ~]$ top
Naming: A "nice" process is considerate of others. Higher nice value = nicer = lower priority. Negative = not nice = higher priority.

nice and renice

# Start process with specific nice value
[user@host ~]$ nice -n 10 ./long-task.sh
# Runs with nice value 10 (lower priority)

# Default nice value is 10 if not specified
[user@host ~]$ nice ./long-task.sh

# Only root can set negative nice values
[root@host ~]# nice -n -5 ./important-task.sh

# Change nice value of running process
[root@host ~]# renice -n 15 -p 1234
1234 (process ID) old priority 0, new priority 15

# Renice by user (all processes owned by user)
[root@host ~]# renice -n 10 -u student

# Regular users can only increase nice (lower priority)
[user@host ~]$ renice -n 5 -p 5678      # Works (lowering priority)
[user@host ~]$ renice -n -5 -p 5678     # Fails (raising priority)
renice: failed to set priority for 5678: Permission denied

Best Practices

Do

  • Use ps/top to investigate before killing
  • Try SIGTERM before SIGKILL
  • Use pgrep to preview pkill targets
  • Use nohup for long-running tasks
  • Nice background jobs to reduce impact
  • Monitor with top for real-time issues
  • Check process owner before killing
  • Understand why a process is misbehaving

Do Not

  • Jump straight to kill -9
  • Kill processes you don't understand
  • Use pkill without previewing matches
  • Kill system processes carelessly
  • Ignore zombie process accumulation
  • Assume process names are unique
  • Forget that kill sends signals, not just kills
  • Neglect to check if process actually stopped
Troubleshooting order: Investigate (ps, top) → Understand the problem → Try gentle solutions first → Escalate if needed

Key Takeaways

1

Investigate: Use ps aux for snapshots, top for real-time monitoring. Understand PID, state, CPU, memory.

2

Jobs: Background with &, suspend with Ctrl+Z, resume with bg/fg. Use nohup to survive logout.

3

Signals: kill PID sends SIGTERM. kill -9 forces. pkill matches patterns. SIGTERM before SIGKILL!

4

Priority: nice starts with priority, renice changes running process. Range -20 to 19, lower is higher priority.

LAB EXERCISES

  • Use ps aux to list all processes and identify high CPU users
  • Monitor system with top, sort by memory, filter by user
  • Run a process in background, suspend it, and resume in foreground
  • Use kill to send SIGTERM, then SIGKILL to a test process
  • Find processes by name with pgrep, terminate with pkill
  • Start a process with nice, change priority with renice

Next: Controlling Services and Daemons