The Process Control Block
The Process Control Block (PCB) is the kernel data structure that represents a single process. Every piece of information the OS needs to manage, schedule, and resume a process is stored in its PCB. When the OS creates a process, it allocates a PCB; when the process terminates, the PCB is freed.
What the PCB Contains
| Field | Purpose |
|---|---|
| PID | Unique integer identifying the process |
| Process state | Current state (new, ready, running, blocked, terminated) |
| Program counter (PC) | Address of the next instruction to execute when resumed |
| CPU registers | Saved values of all general-purpose and special registers |
| Memory management info | Page table base register, memory limits, segment table pointers |
| Open file list | Array of file descriptors pointing to open files, sockets, pipes |
| Scheduling info | Priority, CPU time consumed, time quantum remaining, nice value |
| Accounting info | User ID, group ID, CPU time used, wall-clock time elapsed |
| I/O status | List of I/O devices allocated, pending I/O requests |
| Parent PID | PID of the parent process, forming the process tree |
| Signal handlers | Table mapping signal numbers to handler functions |
In the Linux kernel, the PCB is the task_struct -- a C structure that is over 600 fields wide, containing everything from scheduling information to cgroup membership, security credentials, and namespacing data.
The Process Table
The process table is the collection of all PCBs in the system. It is a kernel-level data structure (typically a hash table or linked list keyed by PID) that allows the OS to quickly look up any process. When the scheduler needs to pick the next process, it scans the process table for processes in the Ready state.
PID Assignment
PIDs are typically assigned sequentially starting from 1 (the init or systemd process). When the maximum PID is reached (default 32768 on Linux, configurable to 4194304), the kernel wraps around and reuses PIDs that are no longer in use. The maximum can be read or set via /proc/sys/kernel/pid_max.
The /proc Filesystem
Linux exposes PCB information through the /proc virtual filesystem. For a process with PID 1234:
/proc/1234/status-- process state, memory usage, threads/proc/1234/maps-- virtual memory regions (text, heap, stack, shared libraries)/proc/1234/fd/-- directory of open file descriptors (symlinks to actual files)/proc/1234/stat-- raw scheduling statistics (used bytopandps)/proc/1234/cmdline-- the command-line arguments used to start the process
This virtual filesystem is generated on-the-fly by the kernel -- no actual files exist on disk. Tools like ps, top, and htop simply read from /proc to display process information.
Real-Life: Inspecting a Process with /proc
Suppose you want to investigate why a Java application (PID 5678) is consuming too much memory. You can read its PCB information directly:
Check the process state and memory:
cat /proc/5678/status
This shows fields like VmRSS (resident set size -- physical memory used), VmSize (total virtual memory), Threads (number of threads), and State (R for running, S for sleeping, Z for zombie).
View the memory map:
cat /proc/5678/maps
Each line shows a virtual address range, permissions (rwxp), and what is mapped there (the binary, shared libraries like libc.so, the heap [heap], and the stack [stack]).
Count open file descriptors:
ls /proc/5678/fd | wc -l
If this number is unexpectedly high (thousands), you may have a file descriptor leak -- the process is opening files or sockets but never closing them.
Process table in action: When you run ps aux, the ps command iterates over every numeric directory in /proc (each one is a PID), reads the stat and status files, and formats the output. The process table is the kernel-side data; /proc is just a window into it.