This second assignment focus is on threads and their synchronization. pthreads o
ID: 3586281 • Letter: T
Question
Explanation / Answer
// Only part1 has been answered
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#define MAX_QUEUE_LENGTH 1000 // initially our queue will store a 1000 elements, to change, just change this #define
// construct the queue datastructure
struct Queue
{
//
int data[MAX_QUEUE_LENGTH];
//
int front;
//
int rear;
//
}typedef Queue;
//
Queue providerQueue = {{}, -1, -1}; // create one queue type variable and initialise front and rear to -1 as queue is empty initially
//
//providerQueue.front = -1;
//providerQueue.front = -1; // initialize before start
//
//providerQueue.rear = -1; // initialize before start
//
pthread_mutex_t provider_mutex = PTHREAD_MUTEX_INITIALIZER; // create a mutex to be used by provider threads to regulate access to shared resource
//
// shared function that writes the random integer produced my provider thread functions to the queue, returns 0 for success, -1 for failure
int writeToQueue(int data)
{
//
if(providerQueue.rear == MAX_QUEUE_LENGTH-1)
{
//
printf("Error : Queue full, cannot write ");
//
return -1;
}
//
else
{
//
providerQueue.rear++; // move rear to the next empty index
//
providerQueue.data[providerQueue.rear] = data;
//
printf("Data written to queue : %d ", data);
//
return 0;
}
}
//
// thread function that is invoked when a thread is created (provider thread)
void* provider_thread_function(void* args)
{
//
int queueData, retVal;
//
while(1)
{
//
queueData = rand(); // generate a random number to insert into the queue
//
pthread_mutex_lock(&provider_mutex); // acquire the mutex
//
retVal = writeToQueue(queueData); // call the shared function
//
pthread_mutex_unlock(&provider_mutex); // release the mutex for other threads once this is done
//
if (retVal == 0)
printf("I am thread %x, data written : %d ", (int)pthread_self(), queueData); // print the thread id
//
else
printf("I am thread %x, data writing failed ", (int)pthread_self());
//
usleep(10000);// sleep for 10ms
}
}
//
//
int buyFromQueue()
{
//
if(providerQueue.rear == -1)
{
//
printf("Error : queue empty ");
//
return -1;
}
//
else
{
//
providerQueue.front++; // advance front to the first available element
//
return providerQueue.data[providerQueue.front]; // return the element
}
}
//
// thread function for buyer threads
void* buyer_thread_function(void* args)
{
//
int data;
//
while(1)
{
//
pthread_mutex_lock(&provider_mutex); // acquire the same mutex as the shared resource is same for both provider and buyer
//
data = buyFromQueue();
//
if (data != -1)
printf("I am buyer thread %x, data : %d ", (int)pthread_self(), data);
//
else
printf("I am buyer thread %x, queue empty ", (int)pthread_self());
//
pthread_mutex_unlock(&provider_mutex); // release the mutex
//
usleep(100000); // sleep for 100ms
//
}
}
int main(int argc, char *argv[])
{
//
pthread_t provider_thread_id[4]; // array to store provider thread ids
//
int i, N;
//
// get the number of buyers from the commandline argument
N = atoi(argv[1]);
//
pthread_t buyer_thread_id[N];
//
// create and start the provider threads
for(i = 0; i < 4; i++)
{
//
pthread_create(&provider_thread_id[i], NULL, provider_thread_function, NULL);
}
//
// create and start the buyer threads
for(i = 0; i < N; i++)
{
//
pthread_create(&buyer_thread_id[i], NULL, buyer_thread_function, NULL);
}
//
// wait only for the first thread to return, may do for all using a loop
pthread_join(provider_thread_id[0], NULL);
//
pthread_join(buyer_thread_id[0], NULL);
//printf("Hello world! ");
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.