Skip to main content
Bytes & Beyond

Process States and Transitions

Understanding the 5 process states, state transitions, and how the OS manages process execution

Process States and Transitions

A process state represents the current condition of a process in the operating system. During its lifetime, a process transitions through several well-defined states. Understanding these states is crucial for grasping how the OS manages processes.

The 5 Process States

Process State Diagram

Process transitions through 5 states: New → Ready → Running ↔ Waiting → Terminated

State 1: NEW

Process is being created by os in Disk (PCB allocated, not in RAM yet).

When: Right after fork() (Unix) or CreateProcess() (Windows) system call.

What happens:

  • OS allocates a PCB
  • Process code is loaded from disk
  • Memory is allocated but process is NOT in RAM yet
  • Process hasn’t started executing

Example:


pid_t pid = fork();  // ← Process P1 is in NEW state here

Next State: Ready (when loaded into RAM)


State 2: READY

Loaded in RAM, waiting in the “Ready Queue” for the CPU.

When: After loaded into memory, but scheduler hasn’t allocated CPU yet

What happens:

  • Process is loaded in RAM
  • All resources are allocated
  • Process is waiting in the “Ready Queue”
  • Many processes can be in READY state simultaneously
  • Scheduler will pick one based on priority

Example:


Ready Queue: [P1] [P2] [P3] [P4]

            Next to run?

Next State: Running (when scheduler allocates CPU)


State 3: RUNNING

Currently executing instructions on the CPU.

When: Scheduler has allocated CPU time to this process

What happens:

  • Process instructions are executing
  • CPU registers contain process’s data
  • Program Counter points to current instruction
  • Only ONE process can be in RUNNING state at a time (on single-core CPU)

Example:


printf("I'm running!\n");  // ← This line is executing NOW
// This process is in RUNNING state

Duration: Limited by time quantum (typically 10-100 milliseconds)

Next State(s):

  • Ready: Time quantum expires (context switch)
  • Waiting: Process calls I/O or blocking operation
  • Terminated: Process calls exit()

State 4: WAITING (Blocked)

Paused, waiting for an event (I/O, Mutex).

When: Process needs something it doesn’t have (I/O, lock, etc.)

What happens:

  • Process can’t continue without the event
  • CPU is released for other processes to use
  • Process is moved to “Wait Queue” for that specific resource
  • Process will remain blocked until event occurs

Common reasons for WAITING:


// Scenario 1: Waiting for file I/O
read(fd, buffer, 100);  // ← Blocks until data is read from disk

// Scenario 2: Waiting for user input
scanf("%d", &x);        // ← Blocks until user types

// Scenario 3: Waiting for a lock
pthread_mutex_lock(&lock);  // ← Blocks until lock is available

// Scenario 4: Waiting for network I/O
recv(socket, buffer, 100);  // ← Blocks until data arrives

// Scenario 5: Sleeping for a duration
sleep(5);               // ← Blocks for 5 seconds

// Scenario 6: Waiting for child process
wait(&status);          // ← Blocks until child exits

Example flow:

Process executes:
  read(disk_fd, buffer, 1024);
  

  
Disk is slow, process can not continue
  

  
Process moves to WAITING state
CPU scheduler picks another READY process
Disk reads data...
  

  
Data is ready, interrupt occurs
Process moves from WAITING → READY
Waits for CPU again...

Next State: Ready


State 5: TERMINATED

Process execution has finished

When: Process calls exit() or is killed

What happens:

  • Process stops executing
  • OS performs cleanup:
    • Closes file descriptors
    • Deallocates memory
    • Terminates child processes (if any)
    • Notifies parent process of exit status
  • PCB may remain briefly (for parent to read exit status)
  • Eventually removed from process table

Normal Termination:


int main() {
    printf("Doing work...\n");
    return 0;          // ← Process terminates normally
}

Abnormal Termination:


kill -9 <PID>         # ← OS forcefully terminates process

Next State: (removed from system)


State Transitions in Detail

1. NEW → READY

Trigger: OS loads process into RAM


When fork() completes:
  ├─ PCB created
  ├─ Memory allocated
  ├─ Process image loaded
  └─ Process moves to READY

2. READY → RUNNING

Trigger: Scheduler allocates CPU time

// Multiple processes waiting:
Ready Queue: [P1] [P2] [P3] [P4]

Scheduler decision:
  if (P1.priority > P2.priority) {
    P1 → RUNNING
  }
  
// Now P1 executes while others wait

3. RUNNING → READY

Trigger: Time quantum expires or higher priority process arrives

Time Quantum Expired:
RUNNING P1 (10ms used)

Scheduler timer interrupt

Save P1 state to PCB

P1 → READY (back to queue)

Load P2 from READY

P2 → RUNNING

4. RUNNING → WAITING

Trigger: Process executes blocking operation

// Process is executing...
RUNNING:
  read(fd, buffer, 100);  // ← Can't continue without data!
  

  
OS detects blocking operation

Save state to PCB

Move process to WAITING

Scheduler picks another READY process

Data arrives (interrupt)

Process → READY (waits for CPU again)

5. WAITING → READY

Trigger: The waited-for event occurs

Waiting for disk read:
  read() call waiting...
  
  ↓ [Disk controller finishes reading]
  
Disk I/O interrupt occurs

OS wakes up process

Process → READY queue
  
Now it waits for CPU again (not for disk anymore)

6. RUNNING → TERMINATED

Trigger: Process calls exit() or receives SIGKILL

// Normal termination
RUNNING:
  printf("Done!\n");
  return 0;  // ← exit(0) called
  

  
OS cleanup:
  ├─ Close files
  ├─ Free memory
  ├─ Notify parent
  └─ Remove from table

Example: Web Server

Multiple client connections:

Client 1        Client 2        Client 3
   │               │               │
   ├──→ P1         ├──→ P2         ├──→ P3
   │               │               │


Timeline:

T=0ms:  P1 RUNNING (processing request)
        P2 READY (waiting for CPU)
        P3 READY (waiting for CPU)

T=5ms:  P1 hits I/O (reads from disk)
        P1 → WAITING
        P2 → RUNNING (scheduler picks next)

T=10ms: P2 finishes quickly, calls exit()
        P2 → TERMINATED
        P3 → RUNNING

T=15ms: P1 disk read completes
        P1 → READY
        P3 still RUNNING

T=20ms: P3 time quantum expires
        P3 → READY
        P1 → RUNNING (back with data)