Session 3.1: Process Synchronization Fundamentals

Understanding process synchronization, critical-section problem, and race conditions

Module 3 2.5 Hours Theory

Learning Objectives

By the end of this session, you will be able to:
  • Understand the need for process synchronization
  • Define the critical-section problem
  • Explain race conditions and their consequences
  • Identify mutual exclusion requirements
  • Analyze synchronization challenges in concurrent systems
  • Recognize common synchronization scenarios
Key Concept

Process synchronization is essential when multiple processes access shared resources concurrently, requiring coordination to ensure data consistency and system correctness.

Introduction to Process Synchronization

Why Synchronization is Needed

In a multiprogramming environment, multiple processes may execute concurrently and share system resources. When processes cooperate and share data, synchronization becomes crucial to maintain data consistency.

The Problem

Without proper synchronization, concurrent access to shared data may result in data inconsistency and unpredictable program behavior.

Concurrent Process Scenario
Process P1
Process P2
↓ ↓
Shared Data/Resource

Multiple processes accessing shared resource simultaneously

Scenarios Requiring Synchronization:
  • Shared Variables: Multiple processes modifying global variables
  • Shared Files: Concurrent file access and modification
  • Shared Memory: Processes communicating through shared memory
  • Hardware Resources: Printer, disk, network access
Consequences of Poor Synchronization:
  • Data Corruption: Inconsistent or invalid data states
  • Lost Updates: One process overwrites another's changes
  • Deadlocks: Processes waiting indefinitely for resources
  • Starvation: Some processes never get access to resources

Critical Section Problem

Understanding Critical Sections
Definition

A critical section is a segment of code where a process accesses shared resources (variables, files, etc.) that must not be concurrently accessed by other processes.

General Structure of a Process:
do {
    // Entry Section
    // Request permission to enter critical section
    
    // CRITICAL SECTION
    // Access shared resources
    
    // Exit Section  
    // Release permission
    
    // Remainder Section
    // Other processing
    
} while (true);
Entry Section

Code that requests permission to enter the critical section. Must implement synchronization mechanism.

Critical Section

The code segment where shared resources are accessed. Only one process should execute this at a time.

Exit Section

Code that releases permission and allows other processes to enter their critical sections.

Remainder Section

The rest of the process code that doesn't involve shared resources.

Classic Example: Bank Account Problem
// Shared variable
int account_balance = 1000;

// Process 1: Deposit $100
temp = account_balance;    // Read: 1000
temp = temp + 100;         // Calculate: 1100
account_balance = temp;    // Write: 1100

// Process 2: Withdraw $50 (executing concurrently)
temp = account_balance;    // Read: 1000 (old value!)
temp = temp - 50;          // Calculate: 950
account_balance = temp;    // Write: 950 (overwrites P1's update!)

// Result: Balance = 950 instead of expected 1050

Race Conditions

Understanding Race Conditions
Definition

A race condition occurs when multiple processes access shared data concurrently, and the final result depends on the particular order of execution (timing) of the processes.

Characteristics of Race Conditions:
  • Non-deterministic: Results vary between executions
  • Timing-dependent: Outcome depends on process scheduling
  • Difficult to debug: May not occur consistently
  • Data corruption: Can lead to inconsistent states
Common Scenarios:
  • Counter increment: Multiple processes incrementing shared counter
  • Linked list operations: Concurrent insertions/deletions
  • File operations: Simultaneous read/write to same file
  • Resource allocation: Multiple processes requesting same resource
Producer-Consumer Race Condition Example:
// Shared variables
int count = 0;        // Number of items in buffer
int buffer[MAX];      // Shared buffer

// Producer Process
while (true) {
    // Produce item
    while (count == MAX);  // Wait if buffer full
    
    buffer[count] = item;  // Add item to buffer
    count++;               // Increment count ← RACE CONDITION!
}

// Consumer Process  
while (true) {
    while (count == 0);    // Wait if buffer empty
    
    item = buffer[count-1]; // Remove item from buffer
    count--;               // Decrement count ← RACE CONDITION!
    
    // Consume item
}
Why Race Conditions Occur

Assembly Level Operations: High-level operations like count++ are not atomic:

count++ translates to:
1. LOAD count, R1     // Load count into register R1
2. ADD R1, 1          // Increment R1
3. STORE R1, count    // Store R1 back to count

If context switch occurs between these instructions,
another process can modify count, causing inconsistency!

Mutual Exclusion

Mutual Exclusion Concept
Definition

Mutual Exclusion (Mutex) ensures that only one process can access a shared resource or execute in its critical section at any given time.

Mutual Exclusion Visualization
Process P1
⚠️
Process P2
↓ MUTEX ↓
Critical Section

Only one process allowed in critical section at a time

Benefits of Mutual Exclusion:
  • Data Consistency: Prevents data corruption
  • Predictable Results: Eliminates race conditions
  • System Integrity: Maintains system state consistency
  • Resource Protection: Prevents resource conflicts
Implementation Challenges:
  • Performance: Synchronization overhead
  • Deadlock: Processes waiting for each other
  • Starvation: Some processes never get access
  • Complexity: Difficult to implement correctly

Critical Section Solution Requirements

Any solution to the critical section problem must satisfy three fundamental requirements:

1. Mutual Exclusion

If process Pi is executing in its critical section, then no other process can be executing in their critical sections simultaneously.

Ensures: Data consistency and prevents race conditions
2. Progress

If no process is executing in its critical section and some processes wish to enter, only those processes not in their remainder section can participate in deciding which will enter next.

Ensures: System makes progress and avoids unnecessary blocking
3. Bounded Waiting

There must be a bound on the number of times other processes are allowed to enter their critical sections after a process has made a request.

Ensures: No process waits indefinitely (prevents starvation)
Additional Considerations
  • Performance: Minimal overhead when not contending for critical section
  • Fairness: Equal opportunity for all processes to enter critical section
  • Simplicity: Easy to understand and implement correctly
  • Portability: Works across different hardware architectures

Real-World Examples

Printer Spooling

Problem: Multiple processes want to print documents

Critical Section: Adding job to print queue

Shared Resource: Print queue data structure

Solution Needed: Ensure only one process modifies queue at a time

Database Transactions

Problem: Multiple users updating same database record

Critical Section: Read-modify-write operations

Shared Resource: Database records

Solution Needed: Transaction isolation and locking

Memory Allocation

Problem: Processes requesting memory from heap

Critical Section: Updating free memory list

Shared Resource: Memory management data structures

Solution Needed: Atomic memory allocation operations

Network Buffer

Problem: Multiple threads accessing network buffer

Critical Section: Reading/writing buffer contents

Shared Resource: Network buffer and pointers

Solution Needed: Synchronized buffer access

Session Summary

Key Takeaways:
  • Process synchronization is essential for maintaining data consistency in concurrent systems
  • Critical sections are code segments that access shared resources and require exclusive access
  • Race conditions occur when the outcome depends on the timing of process execution
  • Mutual exclusion ensures only one process accesses shared resources at a time
  • Critical section solutions must satisfy mutual exclusion, progress, and bounded waiting
  • Synchronization problems are common in real-world systems and applications
Important Concepts:
  • Critical Section: Code segment accessing shared resources
  • Race Condition: Timing-dependent execution results
  • Mutual Exclusion: Exclusive access to shared resources
  • Atomic Operations: Indivisible operations that complete without interruption
  • Data Consistency: Maintaining valid and predictable data states
Next Session

Session 3.2: Synchronization Solutions
Peterson's solution, synchronization hardware, atomic operations, and memory barriers

Study Tips:
  • Practice identifying critical sections in code examples
  • Understand why high-level operations are not atomic at machine level
  • Work through race condition scenarios step by step
  • Memorize the three requirements for critical section solutions
  • Relate synchronization concepts to real-world examples