A TA that helps undergraduate students with their programming assignments during
ID: 3903602 • Letter: A
Question
A TA that helps undergraduate students with their programming assignments during regular office hours. The TA’s office is small and has room for only 1 desk with a chair and computer. There are 3 chairs in the hallway outside the office where students can sit and wait if the TA is currently helping another student. When there are no students who need help during office hours, the TA sits at the desk and takes a nap. If a student arrives during office hours and finds the TA sleeping, the student must awaken the TA to ask for help. If a student arrives and finds the TA currently helping another student, the student sits on one of the chairs in the hallway and waits. If no chairs are available, the student will come back at a later time. Using POSIX threads, mutex locks, and semaphores, implement a solution that coordinates the activities of the TA and the students. Details for this assignment are provided below.
The Students and the TA Using Pthreads (Section 4.4.1), begin by creating n students. Each will run as a separate thread. The TA will run as a separate thread as well. Student threads will alternate between programming for a period of time and seeking help from the TA. If the TA is available, they will obtain help. Otherwise, they will either sit in a chair in the hallway or, if no chairs are available, will resume programming and will seek help at a later time. If a student arrives and notices that the TA is sleeping, the student must notify the TA using a semaphore. When the TA finishes helping a student, the TA must check to see if there are students waiting for help in the hallway. If so, the TA must help each of these students in turn. If no students are present, the TA may return to napping. To simulate students programming in students threads, and the TA providing help to a student in the TA thread, the appropriate threads should sleep (by invoking sleep()) for a random of time (up to three seconds).
The total number of students, the number of chairs, and the number of times a student seeks the TA help are passed as command line parameters as shown below ./TA #students #chairs #help (e.g. ./TA 11 5 4) Once a student thread takes the required number of help from the TA, it should terminate. Once all the student threads are terminated, the TA thread be terminated, and finally the main program should be terminated.
Explanation / Answer
Code:
#include "stdio.h"
#include "stdlib.h"
#include "pthread.h"
#include "semaphore.h"
#include "stdint.h"
#include "malloc.h"
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
//Define the some constant values using macros
#define MAX_SLEEP_TIME 3
#define NUM_OF_STUDENTS 4
#define NUM_OF_HELP 2
#define NUM_OF_SEATS 2
//Declare an array of threads
pthread_t student_array[NUM_OF_STUDENTS];
//Declare a thread for teaching assistant
pthread_t ta_thread;
//Initiale the Pthread mutex.
pthread_mutex_t mutex_lock;
//Create semaphores
sem_t students_sem;
sem_t ta_sem;
//Initialize a variable of int type
int waiting_students = 0;
//Declare an aaray of type int
int thread_helped_counter[NUM_OF_STUDENTS];
// just a random number
unsigned int seed = 92;
//Declare a variabe
int sleep_time;
//Declare an array
int waiting_queue[NUM_OF_HELP];
//Declare the prototype of the functions
void * students(void * param);
void * ta();
void create_students();
void create_ta();
void join_students();
void join_ta();
//Declare a variable
int value;
//Start the main function of the program
int main()
{
// intilize the semaphore for the student.
sem_init(&students_sem,0,1);
// intilize the semaphore for the teaching assistant.
sem_init(&ta_sem,0,1);
//Call the function create_student().
create_students();
//Call the function create_ta().
create_ta();
//Join the threads of student types.
join_students();
//Join the threads of teaching assistant types.
join_ta();
//Destroy the semaphore student_sem
sem_destroy(&students_sem);
//Destroy the semaphore ta_sem
sem_destroy(&ta_sem);
}
//Use the function called Join_ta()
void join_ta()
{
//Check if the thread is not joined
if(pthread_join(ta_thread, NULL))
{
//Print the errpr message on the console
fprintf(stderr, "Error joining thread ");
}
}
//Use the function called Join_students()
void join_students()
{
// this function joins all the student thread
int i;
for(i = 0; i < NUM_OF_STUDENTS; i++)
{
//Check if the thread is not joined
if(pthread_join(student_array[i], NULL))
{
//Print the errpr message on the console
fprintf(stderr, "Error joining thread ");
}
}
}
//Use the function called create_ta()
void create_ta()
{
// This function creats the ta thread
if(pthread_create(&ta_thread, NULL, ta, NULL))
{
//Print the errpr message on the console
fprintf(stderr, "TA thread creation error ");
}
}
//Use the function called create_students()
void create_students()
{
// This function creates 4 student thread
int i;
//Use for loop to create the threads
for(i = 0; i < NUM_OF_STUDENTS; i++)
{
//Allocate the memory space in the heap
int *arg = malloc(sizeof(*arg));
//Assign the value of i to the variable which address is store by the args
*arg = i;
//Create the thread of student type.
if(pthread_create(&student_array[i], NULL, students, (void *)arg))
{
//Print the error message on the console if the thread is not created
fprintf(stderr, "Student thread creation error ");
}
}
//Create the thread of ta type.
if(pthread_create(&ta_thread, NULL, ta, NULL))
{
//Print the error message on the console if the thread is not created
fprintf(stderr, "TA thread creation error ");
}
}
//Define the function called students
void * students(void * param)
{
//Assign the value of pointer variable to the int variable
int i = *((int *)param);
//Calculate the random value for sleep time using rand_r()
int sleeptime = (rand_r(&seed)% MAX_SLEEP_TIME)+1;
//Print the sleep time of ith thread on the console
printf("Student %d programming for %d seconds. ", i, sleeptime);
//Call the sleep()
sleep(sleeptime);
//Lock the mutex
pthread_mutex_lock(&mutex_lock);
//Check if the hepl taken by the student is more than equals to NUM_OF_HELP
if(thread_helped_counter[i] >= NUM_OF_HELP)
{
//Unlock the mutex
pthread_mutex_unlock(&mutex_lock);
//Return the null value to the function
return NULL;
}
//Unlock the mutex
pthread_mutex_unlock(&mutex_lock);
//lock the mutex
pthread_mutex_lock(&mutex_lock);
//Get the value of semaphore of ta_sem
sem_getvalue(&ta_sem, &value);
//Unlock the mutex
pthread_mutex_unlock(&mutex_lock);
//Check if the semaphore value is greater than 0
if(value > 0)
{
//there are students getting help
sem_wait(&ta_sem);
//Lock the mutex
pthread_mutex_lock(&mutex_lock);
//Check if the waiting student is either 0 or 1.
if(waiting_students >= 0&& waiting_students < NUM_OF_SEATS)
{
//perform the following operation if the waiting student is equals to 0
if(waiting_students == 0)
{
//Assign the value to the waiting queue
waiting_queue[0] = i;
//Print the values on the console
printf(" Student %d takes a seat, # of waiting students = %d ",
waiting_queue[0], waiting_students);
//Increase the value of waaiting student by 1
waiting_students++;
}
//perform the following operation if the waiting student is equals to 1
else if(waiting_students == 1)
{
//Assign the value to the waiting queue
waiting_queue[1] = i;
//Print the values on the console
printf(" Student %d takes a seat, # of waiting students = %d "
,waiting_queue[1], waiting_students);
//Increase the value of waaiting student by 1
waiting_students++;
}
//Unlock the mutex
pthread_mutex_unlock(&mutex_lock);
//Call the sem_post() function
sem_post(&students_sem);
//Calculate the sleep_time using rand_r()
sleep_time = (rand_r(&seed)% MAX_SLEEP_TIME)+1;
//Call the sleep()
sleep(sleep_time);
}
else
{
//print the meassage on the console
printf(" waiting list > 2 ");
//seats are full, student will try later so unlock the mutex
pthread_mutex_unlock(&mutex_lock);
//print the message on the console
printf(" Student %d will try later ", i);
//Call the sleep()
sleep((rand_r(&seed)% MAX_SLEEP_TIME)+1);
//call the students() for ith student
students(&i);
}
}
//perform the following opeartion if the semaphore value is less than 0
else
{
//Call the sem_post()
sem_post(&students_sem);
}
//Call the students()
students((void*)&i);
}
//Define the ta() which return type is void pointer
void * ta()
{
//Declare the variables.
int i,result;
//Use the for loop to calculate the result
for(i=0;i< 4; i++)
{
//Calculate the Result
result+=thread_helped_counter[i];
}
//Check if the total help is equal to the 8.
if(result == 8)
{
//all students helped 2 times so return the null value
return NULL;
}
//Call the sem_wait()
sem_wait(&students_sem);
//ta no longer busy so lock the mutex
pthread_mutex_lock(&mutex_lock);
//Calculate the random value for sleep time using rand_r()
sleep_time = (rand_r(&seed)% MAX_SLEEP_TIME)+1;
//perform the following if the waiting students equal to 1 and helped counter is less than 2
if(waiting_students == 1 && thread_helped_counter[waiting_queue[0]] < 2)
{
//Decrease the waiting_students by 1.
waiting_students--;
//Print the helping time of a student and number of waiting student on the console
printf("Helping a student for %d , # of students waiting = %d ",sleep_time, waiting_students);
//Print the student number which is recieving the help
printf("Student %d recieving help ", waiting_queue[0]);
//Increase the helped counter by 1
thread_helped_counter[waiting_queue[0]]++;
}
//perform the following if the waiting students equal to 2 and helped counter is less than 2
else if(waiting_students == 2 && thread_helped_counter[waiting_queue[1]] < 2)
{
//Decrease the waiting_students by 1.
waiting_students--;
//Print the helping time of a student and number of waiting student on the console
printf("Helping a student for %d , # of students waiting = %d ",sleep_time, waiting_students);
//Print the student number which is recieving the help
printf("Student %d recieving help ", waiting_queue[1]);
//Increase the helped counter by 1
thread_helped_counter[waiting_queue[1]]++;
}
//Unlocke the mutex by the student
pthread_mutex_unlock(&mutex_lock);
//Call the sleep()
sleep(sleep_time);
//Call the sem_post()
sem_post(&ta_sem);
//Call the ta() function.
ta();
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.