Process model and PCB
What a process is and how the OS represents it: program versus process, the process image, the process control block and the process table, process identifiers and hierarchy, CPU-bound and I/O-bound processes, and CPU utilization as a function of the degree of multiprogramming.
Why it exists
A computer runs many activities at once, or seems to. The operating system needs one uniform thing to manage: something that owns memory, has a state, can be started, stopped and resumed, and can be protected from the others. That thing is the process. Every other topic in operating systems (scheduling, synchronization, memory management, deadlock) is about processes. GATE asks what is in a process and in the process control block, what information must be saved to resume a process, how processes relate to each other, and how many processes it takes to keep the CPU busy.
Prerequisites
The services a process requests from the kernel come through system calls, which is also how a process is created and destroyed.
Precise definitions
Program and process. A program is a passive file on disk: code and initial data. A process is a program in execution: an active entity with a program counter, registers, a stack and its own memory. One program can be several processes at once (two users running the same editor), each with its own state.
Process image (address space). The memory a process uses:
- text (code): the instructions, normally read-only and shareable;
- data: global and static variables (initialised data and uninitialised, the bss);
- heap: memory allocated at run time (
malloc), growing upward; - stack: activation records of function calls, growing downward.
The same layout appears in C memory layout. Besides memory, a process has CPU state (the program counter and registers) and resources (open files, for example).
Process control block (PCB), also task control block. The kernel data structure that represents a process. It holds everything the OS needs to manage it and to resume it later:
- process identifier (pid), the parent's pid and the user id;
- process state (new, ready, running, waiting, terminated);
- CPU registers and program counter (saved when the process is not running);
- CPU scheduling information: priority, pointers to scheduling queues, time used;
- memory-management information: base and limit registers or the page table pointer, segment tables;
- accounting information: CPU time used, time limits;
- I/O status information: open files, allocated devices.
The process table is the array (or list) of all PCBs. Ready and waiting processes are kept in queues made of PCBs.
Process identification and hierarchy. Every process has a unique pid. A process creates others, the children, with a system call (fork), forming a tree with the first user process as root (init or systemd on Unix-like systems). A process knows its parent's pid (ppid). Some systems, such as Windows, have no such strict tree.
Kinds of process. An I/O-bound process spends most of its time waiting for I/O and runs in short CPU bursts; a CPU-bound process spends most of its time computing, in few long bursts. A good mix keeps both the CPU and the devices busy.
Degree of multiprogramming. The number of processes in memory at the same time. More processes mean the CPU is more likely to have one to run while others wait for I/O.
CPU utilization model. If each process spends a fraction of its time waiting for I/O, and the processes in memory wait independently, the CPU is idle only if all wait at the same moment, which has probability . So
The curve rises steeply for small and then flattens: each additional process helps less. It ignores the cost of context switching and the memory needed by each extra process.
How it works
The animation shows the process table of the smallest possible example: one process calls fork(). The kernel allocates a new PCB, gives it a new pid and records the parent, and the child starts as a copy of the parent: same code and the same next instruction, but its own data. The table shows each process's pid, its parent, its state and what it has printed.
One fork: parent and child: start
Interpreted, not typed1int main(void) {2 fork();P13 puts("hello");4}
Step 0
One process, P1, starts running the fragment. fork() makes a new process that is a copy of the caller; the call returns the child's process id in the parent and 0 in the child, and afterwards both continue with the statement after the call. Step through to watch the process table grow. (The order in which the processes run is decided by the scheduler; here the lowest numbered runnable process always goes first, but any order gives the same COUNTS.)
Worked examples
EX 1Program or process?
EasyThe file /bin/ls is a program. If two users type ls at the same time there are two processes, with two PCBs and two separate stacks, data areas and program counters; the read-only code can be shared in memory. A process is created when the program starts to run and disappears when it finishes, while the program file stays. In the animation both processes run the same code, listed on the left, but each has its own next-line marker.
EX 2What belongs in the PCB?
Easy| Information | In the PCB? |
|---|---|
| Program counter and register values when not running | yes |
| Process state | yes |
| Page table pointer or base and limit | yes |
| List of open files | yes (or a pointer to the table) |
| Priority and accounting | yes |
| The process's variable values | no (they are in its memory; the PCB only points to the memory) |
| The contents of an open file | no |
| The instructions of the program | no (in memory, found through the memory-management fields) |
The PCB is the "everything the kernel needs to put the process back where it was", which is why the context switch is largely a matter of saving and loading PCB fields.
EX 3CPU utilization and the degree of multiprogramming
MediumEach process waits for I/O 80% of the time ().
#include <stdio.h>
int main(void) {
/* a fraction p of a process's time is spent waiting for I/O; with n processes in memory the CPU is idle only if all of them wait at once */
double p = 0.8;
double prod = 1;
for (int n = 1; n <= 8; n++) {
prod *= p;
printf("n = %d processes: CPU utilization = 1 - %.1f^%d = %5.1f%%\n", n, p, n, 100 * (1 - prod));
}
return 0;
}n = 1 processes: CPU utilization = 1 - 0.8^1 = 20.0%
n = 2 processes: CPU utilization = 1 - 0.8^2 = 36.0%
n = 3 processes: CPU utilization = 1 - 0.8^3 = 48.8%
n = 4 processes: CPU utilization = 1 - 0.8^4 = 59.0%
n = 5 processes: CPU utilization = 1 - 0.8^5 = 67.2%
n = 6 processes: CPU utilization = 1 - 0.8^6 = 73.8%
n = 7 processes: CPU utilization = 1 - 0.8^7 = 79.0%
n = 8 processes: CPU utilization = 1 - 0.8^8 = 83.2%Reading it. One process keeps the CPU busy only 20% of the time. Two give , four about 59%. Each extra process adds less: from 7 to 8 only 4.2 percentage points. To reach 90% with one needs , so (since and ).
EX 4How many processes for a target utilization?
MediumA system must keep the CPU at least 95% busy, and each process waits for I/O 60% of the time (). We need , that is . , , so . In general , rounded up.
EX 5What does the child have?
GATE levelAfter fork() the child has its own PCB with a new pid and with its parent's pid recorded; its registers and program counter are copies of the parent's at the time of the call, and its memory is a copy of the parent's (in practice shared copy-on-write, copied page by page only when one of them writes). Open files are inherited: parent and child share the same open file entries, so they share the file offset. What is not copied: the pid, the parent pid, pending signals, the accounting counters (they start at zero). This is why a variable changed in the child is not seen by the parent: the two processes have separate address spaces.
Cheat box
Cheat box
- Program: passive file. Process: program in execution, with registers, stack, data, heap, open files.
- Process image: text, data, heap (up), stack (down).
- PCB: pid, ppid, state, PC and registers, scheduling info, memory management info (page table), accounting, I/O status. Process table = all PCBs.
- Processes form a tree (fork). I/O-bound: short CPU bursts. CPU-bound: long bursts.
- CPU utilization ( = fraction of time waiting for I/O, = degree of multiprogramming). Processes needed: .
- Each process has its own address space; a variable changed in one is not seen in the other.
Traps and GATE patterns
Connections
Builds on
Unlocks
Across subjects
Within this subject
Journeys that pass through here
A process is created and destroyed through system calls and moves between the states shown on process states, fork and exec. Switching the CPU between processes saves and loads the PCB (context switching). A thread is a unit of execution inside a process that shares its address space. The memory layout is that of C memory layout.
PYQs
5 previous year questions from your book. I re-solved each one myself (5 by running or simulating, 0 by reasoning only); the book's key is shown next to my answer. All PYQs
Consider the following code snippet using the
fork() and wait() system calls. Assume that the code
compiles and runs correctly, and that the system
calls run successfully without any errors.
int x = 3;
while (x > 0) {
fork();
printf("hello");
wait(NULL);
x--;
}
The total number of times the printf statement is
executed is ________.Consider the following C program is executed on a
Unix/Linux system:
#include <unistd.h>
int main()
{
int i;
for(i = 0; i < 10; i++)
if(i % 2 == 0)
fork();
return 0;
}
The total number of child processes created is
__________.A process executes the code fork (); fork (); fork (); The total number of child processes created is
- (a)3
- (b)4
- (c)7
- (d)8 OPERATING SYSTEMS
A process executes the following code:
for(i=0;i<n;i++)
fork();
The total number of child processes created is- (a)n
- (b)2n-1
- (c)2n
- (d)2n+1 - 1
Consider the following code fragment:
if (fork() == 0)
{
a = a + 5;
printf("%d, %p\n", a, &a);
}
else
{
a = a - 5;
printf("%d, %p\n", a, &a);
}
Let u, v be the values printed by the parent process
and x, y be the values printed by the child process.
Which one of the following is TRUE?- (a)u = x + 10 and v = y
- (b)u = x + 10 and v ≠ y
- (c)u + 10 = x and v = y
- (d)u + 10 = x and v ≠ y OPERATING SYSTEMS
Self-check
Question 1
A process waits for I/O 70% of the time. What CPU utilization do 3 such processes give?
Show answerHide
, that is 65.7%.
Question 2
Name four items stored in a PCB and one that is not.
Show answerHide
Process state, saved program counter, saved registers and the page-table pointer are in it. The values of the program's variables are not (they are in its memory).
Question 3
After a fork the child changes a global variable. Does the parent see the change?
Show answerHide
No. Parent and child have separate address spaces (a copy, or copy-on-write).
Question 4
How many processes keep the CPU at least 90% busy when each waits for I/O 50% of the time?
Show answerHide
: , , so .
Revision card
One-screen revision
- Process program state; image: text, data, heap, stack.
- PCB: pid, ppid, state, PC and registers, scheduling, memory management, accounting, I/O.
- Tree of processes via fork. Utilization .
- Own address space per process; shared code, shared inherited open files.
References
- ·Silberschatz, Galvin, Gagne, Operating System Concepts, Chapter 3 Processes (process concept, process scheduling, operations on processes)
- ·Tanenbaum and Bos, Modern Operating Systems, Chapter 2 Processes and Threads (the process model, implementation of processes)
- ·Stallings, Operating Systems: Internals and Design Principles, Chapter 3 Process Description and Control
Verification
The CPU utilization table is produced by the C program on this page (npm run verify:c) and by exact arithmetic in scripts/enum-checks/os_proc.py. The process-table animation comes from an interpreter (scripts/gen-os-proc-traces.py) whose process counts and printed lines are compared in scripts/enum-checks/os_proc.py with the real fork of the host operating system on the page programs and on 20 random programs, and re-checked by tests/os-proc-traces.test.ts. The list of PCB fields is the textbook's; real kernels (Linux task_struct, for example) hold many more fields and name them differently. The utilization formula 1 - p^n assumes the n processes wait for I/O independently, the usual textbook model. Textbook chapter titles are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand. No defect found. Status raised to self-checked; verified needs a textbook or human check.
last verified: never
My notes (saved in this browser)