Producer Produces the Data and Consumer Consume the data.
Conditions:
1) If the Buffer is Full, then the Producer should not generate data.
2) Consumers must not remove data when the buffer is empty.
Solution:
1) Mutex: To acquire a lock on buffer
2) empty: A counting semaphore initial value = n. Because in start buffer is empty.
3) full: A counting semaphore initial value =0. It Tracks the filled slots.
Program:
// Producer-Consumer Problem #include<stdio.h> #include<semaphore.h> #include<pthread.h> #include<unistd.h> #include<stdlib.h> #define MAX 5 #define BufferSize 5 pthread_mutex_t mutex; sem_t empty, full; int in=0,out=0; // to track element in buffer int buffer[BufferSize]; // Critical Section // Producer function void *producer(void *i) { for(int j=0;j<MAX;j++) { sem_wait(&empty); // if producer is not full then empty-- // get lock on buffer pthread_mutex_lock(&mutex); //generate item randomly int item = rand() % 10; buffer[in] = item; printf("\n\n Producer No: %d Produced item:%d",*(int *)i,buffer[in]); in = (in + 1)%BufferSize; // release lock on buffer pthread_mutex_unlock(&mutex); sem_post(&full); // increment full by 1 sleep(2); } } // Consumer Function void *consumer(void *i) { for(int j=0;j<MAX;j++) { // Not consume when buffer is empty sem_wait(&full); pthread_mutex_lock(&mutex); int item = buffer[out]; printf("\n Consumer No: %d Consumed Item: %d",*(int *)i, item); out = (out+1)%BufferSize; pthread_mutex_unlock(&mutex); sem_post(&empty); // increment empty by 1 } } int main() { // Creating Producer Consumer threads. pthread_t prod[BufferSize], cons[BufferSize]; pthread_mutex_init(&mutex,NULL); // initializing empty and full semaphore sem_init(&empty,0,BufferSize); sem_init(&full,0,0); // initializing the array // int *arr = (int*) malloc(BufferSize * sizeof(int)); int arr[] = {1,2,3,4,5,6,7,8,9,10}; for(int i=0;i<BufferSize;i++) { arr[i] = i+1; pthread_create(&prod[i],NULL,(void *)producer,(void *) &arr[i]); pthread_create(&cons[i],NULL,(void *)consumer,(void *) &arr[i]); } for(int i=0;i<BufferSize;i++) { pthread_join(prod[i],NULL); pthread_join(cons[i],NULL); } pthread_mutex_destroy(&mutex); sem_destroy(&empty); sem_destroy(&full); return 0; }
Output: