Skip to content

seifmaazouz/producer-consumer-commodity-monitor

Repository files navigation

Producer-Consumer Commodity Price Monitor

A real-time commodity price monitoring system implementing the classic Bounded-Buffer Producer-Consumer Problem using System V IPC (Inter-Process Communication) mechanisms. This project demonstrates concurrent process synchronization using semaphores and shared memory.

📋 Table of Contents

🎯 Overview

This project simulates a real-time commodity trading dashboard where multiple Producer processes generate live price updates for various commodities (GOLD, SILVER, CRUDEOIL, etc.), while a single Consumer process displays these prices in a dynamic, color-coded terminal dashboard.

The implementation showcases:

  • Bounded-buffer synchronization using semaphores
  • Shared memory for inter-process communication
  • Normal distribution for realistic price simulation
  • Real-time terminal UI with color indicators and trend arrows

✨ Features

Producer

  • Concurrent price generation for up to 11 different commodities
  • Configurable parameters: mean price (μ), standard deviation (σ), update interval
  • Normal distribution price simulation for realistic market behavior
  • Detailed logging with nanosecond-precision timestamps
  • Graceful shutdown handling (SIGINT, SIGTSTP)

Consumer

  • Real-time dashboard displaying all commodity prices
  • Moving average calculation (current + past 4 readings)
  • Visual indicators:
    • 🟢 Green ↑: Price increased
    • 🔴 Red ↓: Price decreased
    • 🔵 Blue: No change
  • Alphabetically sorted commodity display
  • Non-blocking updates using ANSI escape sequences

🏗️ System Architecture

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Producer 1 │     │  Producer 2 │ ... │  Producer N │
│   (GOLD)    │     │  (SILVER)   │     │   (ZINC)    │
└──────┬──────┘     └──────┬──────┘     └──────┬──────┘
       │                   │                    │
       └───────────┬───────┴────────────────────┘
                   │
                   ▼
          ┌────────────────┐
          │ Shared Memory  │
          │ (Circular      │
          │  Buffer)       │
          └────────┬───────┘
                   │
          ┌────────▼────────┐
          │   Semaphores    │
          │ • Mutex         │
          │ • Empty Slots   │
          │ • Full Slots    │
          └────────┬────────┘
                   │
                   ▼
          ┌────────────────┐
          │   Consumer     │
          │  (Dashboard)   │
          └────────────────┘

Synchronization Mechanism

  • Mutex Semaphore: Ensures mutual exclusion for buffer access
  • Empty Semaphore: Tracks available slots in the buffer
  • Full Semaphore: Tracks filled slots ready for consumption

📦 Prerequisites

  • Operating System: Linux/Unix (uses System V IPC)
  • Compiler: g++ with C++17 support
  • Build Tool: make
  • System Libraries:
    • sys/shm.h (Shared Memory)
    • sys/sem.h (Semaphores)
    • sys/ipc.h (IPC mechanisms)

🚀 Installation

  1. Clone the repository:

    git clone <repository-url>
    cd producer-consumer-commodity-monitor
  2. Compile the project:

    make

    This will generate two executables:

    • producer - Producer process
    • consumer - Consumer dashboard
  3. Clean build artifacts (optional):

    make clean

💻 Usage

Starting the Consumer (Dashboard)

The consumer must be started first to initialize shared memory and semaphores:

./consumer <buffer_size>

Example:

./consumer 50

Starting Producers

Launch one or more producers (in separate terminals or background processes):

./producer <COMMODITY> <mean_price> <std_dev> <interval_ms> <buffer_size>

Parameters:

  • COMMODITY: Name of the commodity (max 10 characters)
  • mean_price: Mean price (μ) for normal distribution
  • std_dev: Standard deviation (σ) for price variance
  • interval_ms: Sleep interval between price updates (milliseconds)
  • buffer_size: Size of bounded buffer (must match consumer's buffer size)

Examples:

# Gold prices: mean=$1800, σ=$20, update every 3 seconds
./producer GOLD 1800 20 3000 50 &

# Natural Gas: mean=$7.1, σ=$0.5, update every 200ms
./producer NATURALGAS 7.1 0.5 200 50 &

# Silver prices: mean=$25, σ=$1, update every 5.5 seconds
./producer SILVER 25 1 5500 50 &

Running All Commodities

Use the provided make run target to start all 11 commodities simultaneously:

make run

This will launch the consumer and 11 producers with pre-configured parameters.

Stopping the System

  • Consumer: Press Ctrl+C to gracefully shutdown
  • Producers: Will automatically detect consumer shutdown and terminate
  • Force Stop: Press Ctrl+Z (handled by SIGTSTP)

🔧 Implementation Details

Shared Memory Structure

struct Commodity {
    char name[11];      // Commodity name
    double price;       // Current price
};

struct SharedMemory {
    int in;             // Write index (circular buffer)
    int out;            // Read index (circular buffer)
    int size;           // Buffer capacity
    bool finished;      // Shutdown flag
    Commodity buffer[]; // Flexible array member
};

Semaphore Operations

// Wait (P operation / Down)
semWait(semId, SEM_INDEX);

// Signal (V operation / Up)
semSig(semId, SEM_INDEX);

Producer Logic Flow

  1. Generate random price using normal distribution
  2. Log: "generating a new value"
  3. Wait on EMPTY_SEM (ensure buffer has space)
  4. Log: "trying to get mutex on shared buffer"
  5. Wait on MUTEX_SEM (acquire lock)
  6. Write commodity to buffer
  7. Log: "placing price on shared buffer"
  8. Update circular buffer index
  9. Signal MUTEX_SEM (release lock)
  10. Signal FULL_SEM (indicate new data available)
  11. Sleep for specified interval
  12. Repeat

Consumer Logic Flow

  1. Initialize dashboard table
  2. Wait on FULL_SEM (ensure data available)
  3. Wait on MUTEX_SEM (acquire lock)
  4. Read commodity from buffer
  5. Update circular buffer index
  6. Signal MUTEX_SEM (release lock)
  7. Signal EMPTY_SEM (free up slot)
  8. Update price history and calculate moving average
  9. Determine price trend (up/down/unchanged)
  10. Update dashboard display with color coding
  11. Repeat

📊 Commodities Supported

The system supports the following 11 commodities (alphabetically sorted):

  1. ALUMINIUM
  2. COPPER
  3. COTTON
  4. CRUDEOIL
  5. GOLD
  6. LEAD
  7. MENTHAOIL
  8. NATURALGAS
  9. NICKEL
  10. SILVER
  11. ZINC

📝 Example Scenarios

Scenario 1: Single Commodity

# Terminal 1: Start consumer
./consumer 20

# Terminal 2: Start gold producer
./producer GOLD 1850 25 1000 20

Scenario 2: Multiple Commodities

# Terminal 1: Start consumer
./consumer 40

# Terminal 2: Start producers
./producer GOLD 1850 25 1000 40 &
./producer SILVER 24 2 1500 40 &
./producer CRUDEOIL 75 5 800 40 &
./producer NATURALGAS 7.2 0.3 500 40 &

Scenario 3: High-Frequency Trading

# Low latency updates (100ms intervals)
./consumer 100
./producer GOLD 1850 10 100 100 &
./producer SILVER 24 1 100 100 &

🔬 Technical Details

Price Generation

Prices follow a normal distribution N(μ, σ²):

std::normal_distribution<> dist(meanPrice, stdDev);
double price = dist(generator);

Timestamp Format

Nanosecond precision using clock_gettime():

[MM/DD/YYYY HH:MM:SS.mmm]
Example: [12/31/2022 21:45:20.356]

Moving Average Calculation

Average of current price + past 4 readings (5-period SMA):

AvgPrice = (P₀ + P₁ + P₂ + P₃ + P₄) / 5

Color Coding

  • Green (↑): \033[;32m - Price increased
  • Red (↓): \033[;31m - Price decreased
  • Blue ( ): \033[;34m - No change or initial value

IPC Keys

Generated using ftok():

key_t shmKey = ftok("/tmp", 11);  // Shared memory key
key_t semKey = ftok("/tmp", 8);   // Semaphore key

📄 License

This project is part of an academic assignment for educational purposes.


📚 References

  • Operating Systems: Three Easy Pieces - Remzi H. Arpaci-Dusseau
  • System V IPC Documentation
  • Producer-Consumer Problem (Bounded-Buffer Problem)

🛠️ Troubleshooting

Issue: "Shared memory does not exist"

Solution: Start the consumer before any producers.

Issue: "Buffer size doesn't match"

Solution: Ensure all producers use the same buffer size as the consumer.

Issue: Semaphores not cleaning up

Solution: Use ipcs to view and ipcrm to manually remove orphaned IPC resources:

# View IPC resources
ipcs

# Remove shared memory
ipcrm -m <shmid>

# Remove semaphores
ipcrm -s <semid>

Issue: Dashboard not updating

Solution: Check that producers are running and buffer size is adequate.


👥 Authors

Operating Systems Lab (CC373) - Alexandria University

About

A real-time commodity price monitoring system implementing the Producer-Consumer problem using System V IPC, semaphores, and shared memory in C++. Features a dynamic terminal dashboard with 11 commodities and color-coded price trends.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors