#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
#define NUM_PRODUCERS 3
#define NUM_CONSUMERS 2
int buffer[BUFFER_SIZE];
int buffer_index = 0;
sem_t empty, full, mutex;
void *producer(void *thread_id) {
int item;
int producer_id = *(int*)thread_id;
while (1) {
item = rand() % 100; // Generate a random item
sem_wait(&empty); // Wait for an empty slot in the buffer
sem_wait(&mutex); // Acquire the mutex to protect the buffer
// Produce item
printf("Producer %d produced item: %d\n", producer_id, item);
buffer[buffer_index++] = item;
sem_post(&mutex); // Release the mutex
sem_post(&full); // Signal that the buffer is now full
}
pthread_exit(NULL);
}
void *consumer(void *thread_id) {
int item;
int consumer_id = *(int*)thread_id;
while (1) {
sem_wait(&full); // Wait for a full slot in the buffer
sem_wait(&mutex); // Acquire the mutex to protect the buffer
// Consume item
item = buffer[--buffer_index];
printf("Consumer %d consumed item: %d\n", consumer_id, item);
sem_post(&mutex); // Release the mutex
sem_post(&empty); // Signal that the buffer is now empty
}
pthread_exit(NULL);
}
int main() {
srand(time(NULL));
// Initialize semaphores
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
pthread_t producers[NUM_PRODUCERS];
pthread_t consumers[NUM_CONSUMERS];
int i;
// Create producer threads
for (i = 0; i < NUM_PRODUCERS; i++) {
int *thread_id = malloc(sizeof(int));
*thread_id = i;
pthread_create(&producers[i], NULL, producer, (void *)thread_id);
}
// Create consumer threads
for (i = 0; i < NUM_CONSUMERS; i++) {
int *thread_id = malloc(sizeof(int));
*thread_id = i;
pthread_create(&consumers[i], NULL, consumer, (void *)thread_id);
}
// Join producer threads
for (i = 0; i < NUM_PRODUCERS; i++) {
pthread_join(producers[i], NULL);
}
// Join consumer threads
for (i = 0; i < NUM_CONSUMERS; i++) {
pthread_join(consumers[i], NULL);
}
// Destroy semaphores
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}