103 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			103 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <pthread.h>
 | 
						|
#include <semaphore.h>
 | 
						|
#include <unistd.h>
 | 
						|
 | 
						|
#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;
 | 
						|
}
 |