In: Computer Science
he Sleeping Teaching AssistantA university computer science department has a teaching assistant (TA) whohelps undergraduate students with their programming assignments duringregular ofFce hours. The TA’s ofFce is rather small and has room for only onedesk with a chair and computer. There are three chairs in the hallway outsidethe ofFce where students can sit and wait if the TA is currently helping anotherstudent. When there are no students who need help during ofFce hours, theTA sits at the desk and takes a nap. If a student arrives during ofFce hoursand Fnds the TA sleeping, the student must awaken the TA to ask for help. If astudent arrives and Fnds the TA currently helping another student, the studentsits on one of the chairs in the hallway and waits. If no chairs are available, thestudent will come back at a later time
#include <pthread.h>
//Create POSIX threads.
#include <time.h>
//Wait for a random time.
#include <unistd.h>
//Thread calls sleep for specified number of
seconds.
#include <semaphore.h> //To
create semaphores
#include <stdlib.h>
#include <stdio.h>
//Input Output
pthread_t *Students; //N threads
running as Students.
pthread_t TA;
//Separate Thread for TA.
int ChairsCount = 0;
int CurrentIndex = 0;
//Declaration of Semaphores and Mutex Lock.
sem_t TA_Sleep;
sem_t Student_Sem;
sem_t ChairsSem[3];
pthread_mutex_t ChairAccess;
//Declared Functions
void *TA_Activity();
void *Student_Activity(void *threadID);
int main(int argc, char* argv[])
{
int number_of_students;
//a variable taken from the user to create student
threads. Default is 5 student threads.
int id;
srand(time(NULL));
//Initializing Mutex Lock and Semaphores.
sem_init(&TA_Sleep, 0, 0);
sem_init(&Student_Sem, 0, 0);
for(id = 0; id < 3; ++id)
//Chairs array of 3
semaphores.
sem_init(&ChairsSem[id], 0,
0);
pthread_mutex_init(&ChairAccess, NULL);
if(argc<2)
{
printf("Number of Students not
specified. Using default (5) students.\n");
number_of_students = 5;
}
else
{
printf("Number of Students
specified. Creating %d threads.\n", number_of_students);
number_of_students =
atoi(argv[1]);
}
//Allocate memory for Students
Students = (pthread_t*)
malloc(sizeof(pthread_t)*number_of_students);
//Creating TA thread and N Student threads.
pthread_create(&TA, NULL, TA_Activity,
NULL);
for(id = 0; id < number_of_students; id++)
pthread_create(&Students[id],
NULL, Student_Activity,(void*) (long)id);
//Waiting for TA thread and N Student
threads.
pthread_join(TA, NULL);
for(id = 0; id < number_of_students; id++)
pthread_join(Students[id],
NULL);
//Free allocated memory
free(Students);
return 0;
}
void *TA_Activity()
{
while(1)
{
sem_wait(&TA_Sleep); //TA is
currently sleeping.
printf("~~~~~~~~~~~~~~~~~~~~~TA has
been awakened by a student.~~~~~~~~~~~~~~~~~~~~~\n");
while(1)
{
// lock
pthread_mutex_lock(&ChairAccess);
if(ChairsCount
== 0)
{
//if chairs are empty, break the loop.
pthread_mutex_unlock(&ChairAccess);
break;
}
//TA gets next
student on chair.
sem_post(&ChairsSem[CurrentIndex]);
ChairsCount--;
printf("Student
left his/her chair. Remaining Chairs %d\n", 3 - ChairsCount);
CurrentIndex =
(CurrentIndex + 1) % 3;
pthread_mutex_unlock(&ChairAccess);
// unlock
printf("\t TA
is currently helping the student.\n");
sleep(5);
sem_post(&Student_Sem);
usleep(1000);
}
}
}
void *Student_Activity(void *threadID)
{
int ProgrammingTime;
while(1)
{
printf("Student %ld is doing
programming assignment.\n", (long)threadID);
ProgrammingTime = rand() % 10 +
1;
sleep(ProgrammingTime);
//Sleep for a random time period.
printf("Student %ld needs help
from the TA\n", (long)threadID);
pthread_mutex_lock(&ChairAccess);
int count = ChairsCount;
pthread_mutex_unlock(&ChairAccess);
if(count < 3)
//Student tried to sit on a chair.
{
if(count ==
0) //If student sits on first empty
chair, wake up the TA.
sem_post(&TA_Sleep);
else
printf("Student %ld sat on a chair waiting for
the TA to finish. \n", (long)threadID);
// lock
pthread_mutex_lock(&ChairAccess);
int index =
(CurrentIndex + ChairsCount) % 3;
ChairsCount++;
printf("Student
sat on chair.Chairs Remaining: %d\n", 3 - ChairsCount);
pthread_mutex_unlock(&ChairAccess);
// unlock
sem_wait(&ChairsSem[index]);
//Student leaves his/her chair.
printf("\t
Student %ld is getting help from the TA. \n",
(long)threadID);
sem_wait(&Student_Sem);
//Student waits to go next.
printf("Student
%ld left TA room.\n",(long)threadID);
}
else
printf("Student
%ld will return at another time. \n", (long)threadID);
//If student
didn't find any chair to sit on.
}
}