Producer-Consumer Problem Simulation

Control Panel

3 5 10
Slow 5 Fast
Slow 3 Fast
P
Producer
C
Consumer

Shared Buffer

Items Produced
0
Items Consumed
0
Buffer Utilization
0%
Current Buffer State
Empty

Semaphore Values

Empty: 5
Full: 0
Mutex: 1

Event Log

System initialized. Ready to start simulation.

Detailed Problem Description

The Producer-Consumer problem (also known as the Bounded Buffer problem) is a classic example of multi-process synchronization. It illustrates many of the core challenges in concurrent programming and operating systems design, including:

  • Resource Sharing: Multiple processes accessing a shared resource (the buffer)
  • Process Coordination: Ensuring processes operate in a coordinated manner
  • Mutual Exclusion: Preventing simultaneous access to shared resources
  • Deadlock Avoidance: Preventing situations where processes indefinitely wait for each other
  • Race Conditions: Avoiding inconsistent states due to timing issues
Note: The correct ordering of semaphore operations is crucial. If the mutex is acquired before waiting on empty/full, a deadlock can occur if a process holds the mutex while waiting for buffer space to become available.

Pseudocode Algorithm: Complete Solution

// Shared data
BUFFER_SIZE = N        // Fixed buffer size
buffer[BUFFER_SIZE]    // Shared buffer
in = 0                 // Position for next item to be inserted
out = 0                // Position for next item to be removed
count = 0              // Number of items in buffer

// Semaphores
semaphore mutex = 1    // For mutual exclusion
semaphore empty = N    // Count of empty slots
semaphore full = 0     // Count of filled slots

// Producer process
procedure Producer() {
    while (true) {
        item = produce_item()   // Generate new item
        
        wait(empty)             // Wait if no empty slots
        wait(mutex)             // Enter critical section
        
        // Critical section - modify shared buffer
        buffer[in] = item       // Add item to buffer
        in = (in + 1) % BUFFER_SIZE  // Circular increment
        count = count + 1       // Update item count
        
        signal(mutex)           // Exit critical section
        signal(full)            // Signal that new item is available
    }
}

// Consumer process
procedure Consumer() {
    while (true) {
        wait(full)              // Wait if no items available
        wait(mutex)             // Enter critical section
        
        // Critical section - modify shared buffer
        item = buffer[out]      // Get item from buffer
        out = (out + 1) % BUFFER_SIZE  // Circular increment
        count = count - 1       // Update item count
        
        signal(mutex)           // Exit critical section
        signal(empty)           // Signal that slot is now empty
        
        consume_item(item)      // Process the item
    }
}