#include #include #include #include #include #define BUFFER_SIZE 10 #define NUM_ITEMS 20 // items to be produced/consumed int buffer[BUFFER_SIZE]; int in = 0; int out = 0; sem_t empty; // empty slots semaphore sem_t full; // available items semaphore pthread_mutex_t mutex; // mutex for shared vars void* producer(void* arg) { int item; for (int i = 0; i < NUM_ITEMS; i++) { item = i; // item is set to index // waiting for empty slot sem_wait(&empty); // critical section pthread_mutex_lock(&mutex); // item placement into buffer buffer[in] = item; printf("Produced: %d at index %d\n", item, in); in = (in + 1) % BUFFER_SIZE; // critical section exit pthread_mutex_unlock(&mutex); // empty slot available sem_post(&full); // production time sim using sleep sleep(1); } pthread_exit(NULL); } void* consumer(void* arg) { int item; for (int i = 0; i < NUM_ITEMS; i++) { // waiting for at least one item in the buffer sem_wait(&full); // critical section pthread_mutex_lock(&mutex); // item removal from buffer item = buffer[out]; printf("Consumed: %d from index %d\n", item, out); out = (out + 1) % BUFFER_SIZE; // critical section exit pthread_mutex_unlock(&mutex); // empty slot sem_post(&empty); // consumption time sim using sleep sleep(2); } pthread_exit(NULL); } int main(void) { pthread_t producer_tid, consumer_tid; // semaphore init sem_init(&empty, 0, BUFFER_SIZE); // empty slots init sem_init(&full, 0, 0); // available items init // mutex init pthread_mutex_init(&mutex, NULL); // thread creator if (pthread_create(&producer_tid, NULL, producer, NULL) != 0) { perror("Failed to create producer thread"); exit(EXIT_FAILURE); } if (pthread_create(&consumer_tid, NULL, consumer, NULL) != 0) { perror("Failed to create consumer thread"); exit(EXIT_FAILURE); } // thread completion wait pthread_join(producer_tid, NULL); pthread_join(consumer_tid, NULL); // cleanup of semaphores and mutex sem_destroy(&empty); sem_destroy(&full); pthread_mutex_destroy(&mutex); return 0; }