Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Operating Systems Using Pthreads for Bounded Buffer The purpose of this project

ID: 3851030 • Letter: O

Question

Operating Systems


Using Pthreads for Bounded Buffer

The purpose of this project is to provide you with some hands-on experience in using standard pthreads library to solve producer-consumer problem. For more information on pthreads, you may review the pthreads Web page and the tutorial from Lawrence Livermore National Lab.

In this project, you will design a programming solution to the bounded-buffer problem by using the producer and consumer processes described in process synchronization chapter of your textbook. The producer's job is to generate a piece of data, put it into the buffer and start again. At the same time the consumer is consuming the data (i.e. removing it from the buffer) one piece at a time. The problem is to make sure that the producer won't try to add data into the buffer if it's full and that the consumer won't try to remove data from an empty buffer.

The solution for the producer is to go to sleep if the buffer is full. The next time the consumer removes an item from the buffer, it wakes up the producer who starts to fill thebuffer again. In the same way the consumer goes to sleep if it finds the buffer to be empty. The next time the producer puts data into the buffer, it wakes up the sleeping consumer. The solution can be reached by means of inter-process communication, typically using semaphores. Your solution should avoid any deadlock situation that might occur. The size of the buffer used by the producer and the consumer is 7.

The solution presented in the textbook uses three semaphores: empty and full, which count the number of empty and full slots in the buffer, and mutex, which is a binary (or mutual exclusive) semaphore that protects the actual insertion or removal of items in the buffer.

For this project, standard counting semaphores will be used for empty and full, and a binary semaphore, mutex lock,will be used to represent mutual exclusion. The producer and consumer – running as separate threads – will move random number of items to and from a buffer that issynchronized with these empty, full, and mutex structures. You are required to use the pthread package to solve this problem in this project.

Programming Tool:

You can use either C or C++.

Project Submission:

Explanation / Answer

Answer for question:

The below code is having with buffer size is 7 and used semaphores with inializse and produce and consumere and insert and remove items from buffer functions.

See the below code :

// Header files include section
#include <iostream>
#include <pthread.h>
#include <vector>
#include <cstdlib>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>


// Buffer Size is define as 7
#define BUFFER_SIZE 7

// Functions Declaration Section for Producer and Consumer
void InitializeData();
void *Produce(void *);
void *Consume(void *);
int InsertItem(int);
int RemoveItem(int *);

// Global counter Variable declaration
int iCounter;
pthread_mutex_t mutex;
sem_t full, empty;

// Declared Buffer with size 7
int buffer[BUFFER_SIZE];

// Main method
int main(int argc , char * argv[])
{
InitializeData();
pthread_t ProducerThread , ConsumerThread;
int *aa = new int [10];
for(int i = 0 ; i < 10 ; i++)
{
aa[i] = i;
pthread_t t;
pthread_create(&t , NULL, Produce , &aa[i]);
printf("Creating Producer %d ", i);
}
int *bb = new int[10];
for(int i = 0 ; i < 10 ; i++)
{
bb[i] = i;
pthread_t t;
pthread_create(&t , NULL, Consume , &bb[i]);
printf("Creating Consumer %d ", i);
}

//sleep(5);
delete [] aa;
delete [] bb;

return 0;
}

// InitializeData of thread and semaphore with null values
void InitializeData()
{
pthread_mutex_init(&mutex , NULL);
sem_init(&full , 0 ,0);
sem_init(&empty , 0 , BUFFER_SIZE);

iCounter = 0;

}

// Function or produce the item and placed in Buffer
void * Produce(void * Param)
{
int item;

while(1)
{
//sleep(1);
item = rand() % 100;
sem_wait(&empty);
pthread_mutex_lock(&mutex);
int iMsg = InsertItem(item);
  
if(iMsg == -1){
printf("Error Inserting Item ");
}else
{
printf("Produced Item :: %d Thread No :: %d ", item , *((int *)Param));
}
pthread_mutex_unlock(&mutex);
sem_post(&full);
  
}
}

// Consume function with consume
void * Consume(void * Param)
{
int item;

while(1)
{
//sleep(1);
sem_wait(&full);
pthread_mutex_lock(&mutex);
int iMsg = RemoveItem(&item);
  
if(iMsg == -1){
printf("Error Removing Item ");
}else
{
printf("Consumed Item :: %d Thread No :: %d ", item ,*((int *)Param));
}
pthread_mutex_unlock(&mutex);
sem_post(&empty);
  
}
}

//Insert Item into Buffer
int InsertItem(int item)
{
if(iCounter < BUFFER_SIZE)
{
buffer[iCounter] = item;
iCounter++;
return 1;
}
else{
return -1;
}

}

// Remove the Item from Buffer
int RemoveItem(int *item)
{
if(iCounter > 0)
{
*item = buffer[iCounter - 1];
iCounter--;
return 1;
}
else{
return -1;
}
}