Lab 06: Process Management & Signals

Time: 30 minutes | Level: Practitioner | Docker: docker run -it --rm ubuntu:22.04 bash


Overview

Processes are the heartbeat of a Linux system. Every running program — from your shell to a web server — is a process with its own PID, resources, and lifecycle. In this lab you'll learn to inspect processes, send signals, adjust priorities, and understand the /proc virtual filesystem.


Step 1: Listing Processes with ps

The ps command is your primary tool for inspecting running processes.

# BSD-style: all processes with user info
ps aux | head -8

# UNIX-style: full format with PPID
ps -ef | head -8

📸 Verified Output:

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0   4364  3220 ?        Ss   05:48   0:00 bash -c ps aux | head -8
root           7  0.0  0.0   7064  2936 ?        R    05:48   0:00 ps aux
root           8  0.0  0.0   2804  1528 ?        S    05:48   0:00 head -8

UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 05:48 ?        00:00:00 bash -c ps -ef | head -8
root           7       1  0 05:48 ?        00:00:00 ps -ef
root           8       1  0 05:48 ?        00:00:00 head -8

💡 Column cheatsheet: PID = process ID, PPID = parent PID, %CPU/%MEM = resource usage, VSZ = virtual memory, RSS = resident (physical) memory, STAT = state (S=sleeping, R=running, Z=zombie, T=stopped).


Step 2: Understanding Process States & STAT Codes

📸 Verified Output:

💡 STAT flags: s = session leader, l = multi-threaded, + = foreground process group, < = high priority, N = low priority (nice). A Z state means zombie — the process is dead but not yet reaped by its parent.


Step 3: Exploring /proc/PID/

The /proc filesystem is a virtual window into the kernel's view of every process.

📸 Verified Output:

💡 Key /proc/PID files: cmdline = exact command, status = process info, fd/ = open file descriptors, maps = memory map, environ = environment variables, exe = symlink to the executable binary.


Step 4: Signals — Communicating with Processes

Linux signals are software interrupts sent to processes. You have 64 available.

📸 Verified Output:

Most important signals:

Signal
Number
Default Action
Can Ignore?

SIGHUP

1

Reload config / terminate

Yes

SIGINT

2

Interrupt (Ctrl+C)

Yes

SIGKILL

9

Immediately kill

NO

SIGTERM

15

Graceful terminate

Yes

SIGSTOP

19

Pause/freeze process

NO

SIGCONT

18

Resume paused process

Yes

💡 SIGKILL vs SIGTERM: Always try SIGTERM (15) first — it lets the process clean up. Only escalate to SIGKILL (9) if the process ignores SIGTERM. SIGKILL cannot be caught or blocked.


Step 5: Sending Signals with kill, pkill, and pgrep

📸 Verified Output:

💡 pgrep vs pidof: pgrep nginx matches by name pattern and supports -u user filtering. pidof nginx finds exact name matches. pgrep -a shows the full command line alongside PIDs.


Step 6: killall — Kill by Process Name

📸 Verified Output:

💡 killall vs pkill: killall matches exact process names; pkill uses patterns and supports regex. Use killall -s SIGHUP nginx to send HUP to all nginx workers for a graceful reload.


Step 7: Process Priority with nice and renice

Linux scheduling priority runs from -20 (highest) to 19 (lowest). Only root can set negative values.

📸 Verified Output:

💡 When to use nice: CPU-intensive background tasks (backups, video encoding, database dumps) should run with nice -n 15 or higher to avoid stealing CPU from interactive processes. Use nice -n -10 (requires root) to boost critical services.


Step 8: Capstone — Process Lifecycle Management Scenario

Scenario: You're a sysadmin. A batch job is consuming too many resources and needs to be gracefully managed.

📸 Verified Output:

💡 Zombie processes: If a parent exits without calling wait() on its children, those children become zombies (Z state in ps). They consume no CPU/memory — only a PID slot. They disappear when the parent reads their exit status (or when init/systemd adopts them).


Summary

Command
Purpose
Example

ps aux

List all processes (BSD style)

ps aux | grep nginx

ps -ef

List all processes (UNIX style)

ps -ef | grep 1234

kill -15 PID

Send SIGTERM (graceful stop)

kill -15 4521

kill -9 PID

Send SIGKILL (force stop)

kill -9 4521

kill -STOP PID

Pause/freeze a process

kill -STOP 4521

kill -CONT PID

Resume a frozen process

kill -CONT 4521

pkill name

Kill by process name pattern

pkill -f "python app.py"

pgrep name

Find PIDs by name

pgrep -c nginx

killall name

Kill all by exact name

killall apache2

nice -n N cmd

Start with priority N

nice -n 15 backup.sh

renice -n N -p PID

Change running priority

renice -n 10 -p 1234

/proc/PID/

Process info directory

cat /proc/1/status

Last updated