1. Process Fundamentals

What is a Process?

Definition: A process is a program in execution.

It is crucial to distinguish between a program and a process. A program is a passive entity, such as a file containing a list of instructions stored on disk (often called an executable). A process is an active entity, with a program counter specifying the next instruction to execute and a set of associated resources.

A single program can trigger multiple processes. For example, if you open three terminal windows, you are running three separate instances (processes) of the bash program.

Process Components

The kernel maintains a data structure for each process (the Process Control Block) containing:

  • Process ID (PID): A unique numerical identifier.
  • Parent Process ID (PPID): The PID of the process that spawned this one.
  • Memory Space:
    • Text Segment: The executable code.
    • Data Segment: Global variables.
    • Heap: Dynamically allocated memory.
    • Stack: Local variables and function call frames.
  • File Descriptors: References to open files (0=stdin, 1=stdout, 2=stderr).
  • Environment Variables: Configuration (PATH, USER, etc.).
  • Ownership: User ID (UID) and Group ID (GID).

Process States

A process is always in one of the following states:

State Code Description
Running R Currently executing or waiting in the run queue.
Sleeping S Interruptible sleep (waiting for an event/signal).
Disk Sleep D Uninterruptible sleep (usually waiting for I/O). Cannot be killed.
Stopped T Stopped by a signal (e.g., SIGSTOP or Ctrl+Z).
Zombie Z Terminated but not yet reaped by parent.

Process Creation

In Linux, process creation is a two-step mechanism:

  1. fork(): Creates an exact copy of the current process. The child inherits the parent's memory (via Copy-on-Write), file descriptors, and environment.
  2. exec(): Replaces the current process image with a new program.

Init Process (PID 1): The ancestor of all processes. It is started by the kernel at boot time and is responsible for starting other system services.

2. Process Management Commands

Viewing Processes

The primary tool for viewing processes is ps.

# Standard syntax (BSD style) $ ps aux # Standard syntax (System V style) $ ps -ef

Common Column Meanings:

  • VSZ (Virtual Memory Size): Total memory accessible by the process (including swap).
  • RSS (Resident Set Size): Physical RAM actually used.
  • STAT: The process state code (R, S, Z, etc.).

Other Monitoring Tools:

  • top / htop: Real-time interactive monitoring.
  • pstree: Visualizes the parent-child hierarchy.
  • pgrep: Search for processes by name (e.g., pgrep -a python).
  • /proc: The filesystem interface to the kernel. Try ls /proc/$$ to see your shell's info.

Process Control

Command Description
kill [pid] Send a signal to a process (default is SIGTERM).
killall [name] Kill all processes with a specific name.
pkill [pattern] Signal processes matching a pattern.
nice Start a process with a modified priority.
renice Change priority of a running process.

Background & Foreground

Job control allows you to manage multiple processes from a single shell.

# Start in background $ long_script.sh & # List jobs $ jobs # Bring to foreground $ fg %1 # Suspend current foreground process Ctrl+Z # Resume suspended process in background $ bg %1

3. Signals in Depth

What are Signals?

Definition: Signals are software interrupts used for inter-process communication. They are asynchronous notifications sent to a process to notify it of an event.

Common Signals (Essential List)

Signal ID Action Description
SIGHUP 1 Term Hangup detected. Often used to reload config.
SIGINT 2 Term Interrupt from keyboard (Ctrl+C).
SIGQUIT 3 Core Quit from keyboard (Ctrl+\).
SIGKILL 9 Term Force kill. Cannot be caught or ignored.
SIGSEGV 11 Core Invalid memory reference (Segmentation fault).
SIGTERM 15 Term Termination signal. The polite way to ask a process to stop.
SIGSTOP 19 Stop Stop process execution. Cannot be caught.
SIGTSTP 20 Stop Stop typed at terminal (Ctrl+Z).

Sending Signals

# Syntax: kill -SIGNAL PID # Polite termination (SIGTERM) $ kill -15 1234 $ kill -TERM 1234 # Force kill (SIGKILL) - Use as last resort $ kill -9 1234 $ kill -KILL 1234 # List all signals $ kill -l

Signal Handling & Trapping

A process can choose how to respond to a signal (except SIGKILL/SIGSTOP). It can:

  • Default: Let the kernel take the default action (usually terminate).
  • Ignore: Throw the signal away.
  • Handle: Run a custom function (signal handler).

C Example (sigaction):

struct sigaction sa; sa.sa_handler = my_handler_function; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; // Register handler for SIGINT sigaction(SIGINT, &sa, NULL);

Bash Example (trap):

trap "echo 'Caught SIGINT! Cleaning up...'; rm temp; exit" SIGINT

4. Zombie and Orphan Processes

Zombie Processes

Definition: A process that has completed execution (via exit()) but still has an entry in the process table.

Why do they exist? The kernel keeps the child's entry so the parent can retrieve its exit status. A zombie is not "alive"—it uses no memory or CPU. It only consumes a PID.

Cleanup: The parent must call wait() or waitpid() to read the exit status. Once read, the zombie is removed ("reaped").

Orphan Processes

Definition: A child process whose parent has terminated.

What happens? Orphans are adopted by the init process (PID 1). Init automatically calls wait() on its children, ensuring they don't become zombies.

Prevention

  • Ensure parent processes call wait().
  • Use signal handlers for SIGCHLD to reap children asynchronously.
  • For daemons, use the "double fork" technique to detach from the terminal and avoid zombie issues.