Topic Overview
PCB (Process Control Block)
Learn Process Control Block structure that stores process state and context information for process management and context switching.
PCB (Process Control Block)
Why This Matters
Think of a PCB like a personnel file for an employee. It contains everything the company needs to know: ID, job description, current task, performance history, etc. When the employee switches tasks, the file is updated. A PCB does the same for processes—it stores all information the OS needs: process ID, CPU state, memory info, scheduling info. When the OS switches between processes, it uses the PCB.
This matters because the OS manages many processes simultaneously. Each process needs its own PCB to track its state. When the OS switches from one process to another (context switch), it saves the current process's state to its PCB and loads the next process's state from its PCB. Understanding PCBs helps you understand how the OS manages processes and performs context switches.
In interviews, when someone asks "How does the OS manage processes?", they're testing whether you understand PCBs. Do you know what information is stored in a PCB? Do you understand how context switching works? Most engineers don't. They just run programs and assume the OS handles it.
What Engineers Usually Get Wrong
Most engineers think "PCB is just process information." But PCB is critical for context switching. When the OS switches processes, it saves CPU registers, program counter, stack pointer, etc. to the PCB, then loads the next process's values. Without PCBs, the OS couldn't switch between processes. Understanding this helps you understand how multitasking works.
Engineers also don't understand that PCBs consume memory. Each process has a PCB (typically a few KB). With thousands of processes, PCBs consume significant memory. Understanding this helps you understand process limits and memory usage.
How This Breaks Systems in the Real World
A service was creating many processes (one per request). Each process had a PCB. With thousands of requests, thousands of PCBs were created, consuming memory. The system ran out of memory. The fix? Use threads instead of processes (threads share a PCB), or use a process pool to reuse processes. Understanding PCBs helps you understand why threads are lighter than processes.
Another story: A service was experiencing slow context switches. The OS was switching between processes frequently, and each switch required saving/loading PCB data. This overhead slowed the system. The fix? Reduce context switches. Use fewer processes, or optimize scheduling. Understanding PCBs helps you understand context switch overhead.
What is a PCB?
PCB (Process Control Block) contains:
- Process identification: Process ID (PID), parent PID
- CPU state: Registers, program counter, stack pointer
- Memory information: Page table, memory limits
- I/O status: Open files, devices
- Scheduling information: Priority, state, CPU time
- Accounting: Start time, CPU time used
Purpose:
- Context switching: Save/restore process state
- Process management: Track process information
- Scheduling: Determine which process to run
- Resource management: Track resources used
PCB Structure
Typical PCB Fields
PCB Structure:
- Process ID (PID)
- Parent Process ID (PPID)
- Process State (Ready, Running, Blocked, etc.)
- Program Counter (PC)
- CPU Registers (AX, BX, CX, DX, SP, etc.)
- Memory Management Info
- Page table pointer
- Memory limits
- Base and limit registers
- I/O Status
- Open files
- I/O devices
- Scheduling Information
- Priority
- CPU time used
- Time quantum remaining
- Accounting Information
- Start time
- CPU time
- Memory used
PCB and Process States
Process states stored in PCB:
- NEW: Process being created
- READY: Process ready to run, waiting for CPU
- RUNNING: Process currently executing
- BLOCKED: Process waiting for I/O or event
- TERMINATED: Process finished
State transitions:
NEW → READY → RUNNING → READY (time slice expired)
RUNNING → BLOCKED (I/O wait)
BLOCKED → READY (I/O complete)
RUNNING → TERMINATED (process ends)
PCB and Context Switching
Context switching uses PCB:
1. Save current process state to PCB
- Save CPU registers
- Save program counter
- Save memory management info
2. Load next process state from PCB
- Load CPU registers
- Load program counter
- Load memory management info
Examples
PCB Implementation
// PCB structure in C
typedef struct {
// Process identification
int pid;
int ppid; // Parent process ID
// Process state
enum {
NEW,
READY,
RUNNING,
BLOCKED,
TERMINATED
} state;
// CPU state
int program_counter;
int stack_pointer;
int registers[16]; // CPU registers
// Memory management
void* page_table;
int memory_base;
int memory_limit;
// I/O status
FILE* open_files[10];
int io_devices[5];
// Scheduling
int priority;
int cpu_time_used;
int time_quantum;
// Accounting
time_t start_time;
int cpu_time;
int memory_used;
} PCB;
PCB Operations
class ProcessControlBlock:
def __init__(self, pid):
# Process identification
self.pid = pid
self.ppid = None
# Process state
self.state = 'NEW'
# CPU state
self.program_counter = 0
self.stack_pointer = 0
self.registers = {
'AX': 0, 'BX': 0, 'CX': 0, 'DX': 0,
'SP': 0, 'BP': 0, 'SI': 0, 'DI': 0
}
# Memory management
self.page_table = None
self.memory_base = 0
self.memory_limit = 0
# I/O status
self.open_files = []
self.io_devices = []
# Scheduling
self.priority = 0
self.cpu_time_used = 0
self.time_quantum = 10 # milliseconds
# Accounting
self.start_time = time.time()
self.cpu_time = 0
self.memory_used = 0
def save_cpu_state(self, cpu_state):
"""Save CPU state to PCB"""
self.program_counter = cpu_state['PC']
self.stack_pointer = cpu_state['SP']
self.registers = cpu_state['registers'].copy()
def restore_cpu_state(self):
"""Restore CPU state from PCB"""
return {
'PC': self.program_counter,
'SP': self.stack_pointer,
'registers': self.registers.copy()
}
def update_state(self, new_state):
"""Update process state"""
self.state = new_state
def get_info(self):
"""Get process information"""
return {
'pid': self.pid,
'state': self.state,
'cpu_time': self.cpu_time,
'memory_used': self.memory_used
}
Common Pitfalls
- Not saving all state: Missing registers causes corruption. Fix: Save all CPU state
- PCB corruption: PCB overwritten. Fix: Protect PCB, use proper locking
- Memory leaks: PCBs not freed. Fix: Free PCB when process terminates
- State inconsistency: PCB state doesn't match process. Fix: Update PCB on state changes
Interview Questions
Beginner
Q: What is a PCB and what information does it store?
A:
PCB (Process Control Block) is a data structure storing all information about a process.
Information stored:
- Process identification: PID, parent PID
- CPU state: Registers, program counter, stack pointer
- Memory information: Page table, memory limits
- I/O status: Open files, devices
- Scheduling: Priority, state, CPU time
- Accounting: Start time, CPU time used
Purpose:
- Context switching: Save/restore process state
- Process management: Track process information
- Scheduling: Determine which process to run
Example:
PCB for Process 123:
PID: 123
State: RUNNING
PC: 0x1234
Registers: [AX=10, BX=20, ...]
Memory: Page table at 0x5000
Priority: 5
Intermediate
Q: Explain how PCB is used in context switching and process scheduling.
A:
Context Switching:
-
Save current process state
# Save CPU state to PCB current_process.pcb.save_cpu_state(cpu_state) current_process.pcb.state = 'READY' -
Select next process
next_process = scheduler.select_next() -
Restore next process state
# Load CPU state from PCB cpu_state = next_process.pcb.restore_cpu_state() next_process.pcb.state = 'RUNNING'
Process Scheduling:
Scheduler uses PCB information:
- State: Only schedule READY processes
- Priority: Higher priority processes first
- CPU time: Track time used for scheduling decisions
- I/O status: Blocked processes not scheduled
Example:
def schedule():
ready_processes = [p for p in processes if p.pcb.state == 'READY']
# Sort by priority
ready_processes.sort(key=lambda p: p.pcb.priority, reverse=True)
# Select highest priority
next_process = ready_processes[0]
# Context switch
switch_context(current_process, next_process)
PCB fields used:
- State: Determine if process can run
- Priority: Scheduling decision
- CPU time: Time slice management
- Registers: Context switching
Senior
Q: Design a PCB management system for an OS that handles millions of processes. How do you optimize PCB storage, context switching, and process lookup?
A:
class PCBManagementSystem {
private pcbs: Map<number, PCB>;
private pcbPool: PCBPool;
private index: ProcessIndex;
constructor() {
this.pcbs = new Map();
this.pcbPool = new PCBPool();
this.index = new ProcessIndex();
}
// 1. PCB Allocation
class PCBPool {
private pool: PCB[];
allocate(pid: number): PCB {
// Reuse from pool or create new
let pcb = this.pool.pop();
if (!pcb) {
pcb = new PCB(pid);
} else {
pcb.reset(pid);
}
return pcb;
}
deallocate(pcb: PCB): void {
// Return to pool
pcb.cleanup();
this.pool.push(pcb);
}
}
// 2. Optimized PCB Structure
class PCB {
// Compact structure for memory efficiency
private compact: CompactPCB;
private extended: ExtendedPCB; // Only when needed
saveCPUState(cpuState: CPUState): void {
// Save only modified registers (lazy saving)
this.compact.modifiedRegisters = this.getModified(cpuState);
this.compact.programCounter = cpuState.PC;
}
}
// 3. Fast Process Lookup
class ProcessIndex {
private byPid: Map<number, PCB>;
private byState: Map<string, Set<number>>;
private byPriority: PriorityQueue;
getByPid(pid: number): PCB {
return this.byPid.get(pid);
}
getReadyProcesses(): PCB[] {
const pids = this.byState.get('READY');
return Array.from(pids).map(pid => this.byPid.get(pid));
}
getHighestPriority(): PCB {
return this.byPriority.peek();
}
}
// 4. Context Switching Optimization
optimizeContextSwitch(): void {
// Lazy register saving: Only save modified registers
// Use CPU hardware support for fast context switch
// Cache frequently accessed PCBs
}
// 5. Memory Optimization
optimizeMemory(): void {
// Compact PCB structure
// Extended info only when needed
// Pool PCBs for reuse
}
}
Features:
- PCB pool: Reuse PCBs to reduce allocation overhead
- Compact structure: Minimize memory usage
- Fast lookup: Index by PID, state, priority
- Lazy saving: Only save modified registers
- Memory efficient: Compact structure, extended when needed
-
PCB: Data structure storing all process information
-
Contents: PID, CPU state, memory info, I/O status, scheduling info
-
Context switching: Save/restore process state using PCB
-
Process scheduling: Scheduler uses PCB information (state, priority)
-
Process states: NEW, READY, RUNNING, BLOCKED, TERMINATED
-
Memory management: PCB stores page table, memory limits
-
Best practices: Save all state, protect PCB, free when process terminates
-
Context Switching - How PCB is used to save and restore process state during context switches
-
Process vs Thread - Understanding processes that have PCBs and how threads relate to PCBs
-
Scheduling Algorithms - How the scheduler uses PCB information (state, priority) for scheduling decisions
-
Memory Management - How PCB stores memory information (page table, memory limits)
-
System Calls - How system calls update PCB information (I/O status, resource usage)
Key Takeaways
PCB: Data structure storing all process information
Contents: PID, CPU state, memory info, I/O status, scheduling info
Context switching: Save/restore process state using PCB
Process scheduling: Scheduler uses PCB information (state, priority)
Process states: NEW, READY, RUNNING, BLOCKED, TERMINATED
Memory management: PCB stores page table, memory limits
Best practices: Save all state, protect PCB, free when process terminates
Related Topics
Context Switching
How PCB is used to save and restore process state during context switches
Process vs Thread
Understanding processes that have PCBs and how threads relate to PCBs
Scheduling Algorithms
How the scheduler uses PCB information (state, priority) for scheduling decisions
Memory Management
How PCB stores memory information (page table, memory limits)
System Calls
How system calls update PCB information (I/O status, resource usage)
What's next?