Lab 3 Develop a C program to simulate producer-consumer problem using semaphores


Objective: The objective is to implement a solution for the producer-consumer problem using semaphores in C programming language. This problem involves synchronizing the actions of multiple producer and consumer threads that share a fixed-size buffer, ensuring that producers don't produce when the buffer is full and consumers don't consume when it's empty. Semaphores are employed to manage the access to the shared buffer, maintaining proper synchronization and avoiding race conditions.

Overview:

  1. Initialization: Initialize the necessary variables including the buffer, semaphores (empty and full), and mutex.
  2. Producer Function: Create a function for the producer thread that generates items and attempts to add them to the shared buffer. Ensure synchronization by using semaphores and mutex to manage access to the buffer.
  3. Consumer Function: Develop a function for the consumer thread that retrieves items from the buffer. Employ semaphores and mutex to control access to the shared buffer and prevent consumption when the buffer is empty.
  4. Main Function: In the main() function, create threads for both the producer and consumer. Manage thread creation, execution, and termination using pthread_create() and pthread_join().
  5. Cleanup: Properly destroy and release the resources such as semaphores and mutex used in the solution to avoid memory leaks.


 #include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int count = 0;
int in = 0;
int out = 0;
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
void *producer(void *arg) {
    int item;
    for (int i = 0; i < 10; ++i) {
        item = i + 1; // Producing item
        sem_wait(&empty);
        pthread_mutex_lock(&mutex);
        buffer[in] = item;
        printf("Produced: %d\n", item);
        in = (in + 1) % BUFFER_SIZE;
        count++;
        pthread_mutex_unlock(&mutex);
        sem_post(&full);
    }
    pthread_exit(NULL);
}
void *consumer(void *arg) {
    int item;
    for (int i = 0; i < 10; ++i) {
        sem_wait(&full);
        pthread_mutex_lock(&mutex);
        item = buffer[out];
        printf("Consumed: %d\n", item);
        out = (out + 1) % BUFFER_SIZE;
        count--;
        pthread_mutex_unlock(&mutex);
        sem_post(&empty);
    }
    pthread_exit(NULL);
}
int main() {
    pthread_t producerThread, consumerThread;
    sem_init(&empty, 0, BUFFER_SIZE);
    sem_init(&full, 0, 0);
    pthread_mutex_init(&mutex, NULL);
    pthread_create(&producerThread, NULL, producer, NULL);
    pthread_create(&consumerThread, NULL, consumer, NULL);
    pthread_join(producerThread, NULL);
    pthread_join(consumerThread, NULL);
    sem_destroy(&empty);
    sem_destroy(&full);
    pthread_mutex_destroy(&mutex);
    return 0;
}


***********************************************************

OUTPUT

opera@opera-virtual-machine:~/Desktop$ gcc -o 1 1.c
opera@opera-virtual-machine:~/Desktop$ ./1
Produced: 1
Produced: 2
Produced: 3
Produced: 4
Produced: 5
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Consumed: 5
Produced: 6
Produced: 7
Produced: 8
Produced: 9
Produced: 10
Consumed: 6
Consumed: 7
Consumed: 8
Consumed: 9
Consumed: 10
opera@opera-virtual-machine:~/Desktop$ 







Comments