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:
