You are on page 1of 11

Seeking-Tutor-Problem

Using POSIX threads, mutex locks, and semaphores, I implemented a solution that synchronizes the
activities of the coordinator, tutors, and the students.

Project Description
The computer science department of EWU runs a programming club to help undergraduate students
with their programming assignments. The club has a coordinator and several tutors to assist the
students. The waiting area of the center has several chairs. Initially, all the chairs are empty. The
coordinator is waiting for the students to arrive. The tutors are either waiting for the coordinator to
notify that there are students waiting or they are busy tutoring. The tutoring area is different from
the waiting area. A student, while programming for his project, decides to go to a club to get help
from a tutor. After arriving at the club, the student sits in an empty chair in the waiting area and waits
to be called for tutoring. If no chairs are available, the student will go back to programming and
come back to the club later. Once a student arrives, the coordinator queues the student based on the
student’s priority, and then the coordinator notifies an idle tutor. A tutor, once woken up, finds the
student with the highest priority and begins tutoring. A tutor after helping a student, waits for the
next student. A student after receiving help from a tutor goes back to programming. The priority of a
student is based on the number of times the student has visited the club. A student visiting the club
for the first time gets the highest priority. In general, a student visiting for the ith time has a priority
higher than the priority of the student visiting for the kth time for any k > i. If two students have the
same priority, then the student who came first has a higher priority. Using POSIX threads, mutex
locks, and semaphores implement a solution that synchronizes the activities of the coordinator,
tutors, and the students. The total number of students, the number of tutors, the number of chairs,
and the number of times a student seeks a tutor’s help are passed as command line arguments.
Once a student thread takes the required number of help from the tutors, it should terminate. Once
all the student threads are terminated, the tutor threads, the coordinator thread, and the main
program should be terminated. Your program should work for any number of students, tutors, chairs
and help sought. Allocate memory for data structures dynamically based on the input parameter(s).

Overview
EWU runs a programming club where undergraduate students get help. Club has a coordinator and
several tutors to assist the students. Students come to waiting area. If there is no available seat they
will go back to programming. Otherwise, they will wait in the waiting area. Coordinator prioritizes
students in a queue and assign them to the tutor. If more than one student has the same priority the
tutor will choose whoever came first. After getting the maximum amount of help student terminate.
When all students get help, tutor will terminate and then coordinator will be terminated. Methods
are:

1. Pthread_create()
2. Pthread_join()
3. Sem_init()
4. Sem_wait()
5. Sem_post()
6. Sem_mutex()

Operating System: Linux

To run this 'projectCode.c' file, we used these command line arguments in terminal:

gcc projectCode.c -o thread -lpthread

./thread

Flowchart

Student has 3 parts:

1. Student has to start programming and seek help from a tutor, student needs to get a seat.
After coming to get seat, if student does not find any seat, then has to go back to
programming and try again later.
2. If a student gets a seat, then coordinator gets a notice and then wait for tutor to be assigned
3. After getting maximum amount of help, the student will stop seeking help.
Coordinator has 3 parts:

1. The coordinator waits for students to come to seek help.


2. Prioritize students according to who has come first.
3. If all students leave, then coordinator notify the tutor and leaves.
Tutor has 3 parts:

1. Tutor waits for the coordinator to be notified if a student has come to seek help.
2. Tutor selects to student to help according to the priority of the student
3. If all students have done seeking help from the tutor, the tutor waits for coordinators
notification to finish work.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX 100000
int
mark_visited[MAX],student_priority[MAX],arrival_time[MAX],total_visit_of_student[MAX],s
tudent_id[MAX],tutor_id[MAX];
int
requesting_order=0,student_done=0,occupied_chair=0,total_chair,total_student,total_tutor,help_
limit;
sem_t student,coordinator,tutored_student[MAX],mutexLock;
void *student_thread(void *student_id)
{
int s_id=*(int*)student_id; //converting void to int
while(1)
{
if(total_visit_of_student[s_id-1] == help_limit)
{
sem_wait(&mutexLock);
student_done++; //how many students have tutored totally
sem_post(&mutexLock);
printf("\n\t student-%d terminates\n",s_id);
if(student_done == total_student) printf("\n\t All Students Have Recieved Help\n");
sem_post(&student); //notify coordinate to terminate
pthread_exit(NULL); //thread ends
}
sem_wait(&mutexLock); //mutex was initially 1, when we call sem_wait(), it turns 0, it is locked
right now
if(occupied_chair == total_chair)
{
sem_post(&mutexLock); //mutex unlockes it, by turning the value 1
continue;
}
occupied_chair++;
requesting_order++; //request number of student, it keeps the track of when the student came
mark_visited[s_id-1]=requesting_order;
printf("\nStudent Thread --> Student-%d takes a Seat.\nStudent Thread --> Empty Chairs = %d\
n",s_id,total_chair-occupied_chair);
sem_post(&mutexLock); //unlocked for other students
sem_post(&student); //notify coordinator that student seated.
sem_wait(&tutored_student[s_id-1]); //wait to be tutored.
printf("\nStudent Thread --> Student-%d Received Help.\n",s_id);
sem_wait(&mutexLock);
total_visit_of_student[s_id-1]++; //tutored times++ after tutoring.
printf("\nStudent Thread --> Student-%d's Priority now is %d\n",s_id,
total_visit_of_student[s_id-1]);
sem_post(&mutexLock);
}
}
void *coordinator_thread()
{
while(1)
{
if(student_done==total_student) //if all students finish, tutors threads and coordinate thread
terminate.
{
for(int i=0; i<total_tutor; i++) sem_post(&coordinator); //notify tutors to terminate
printf("\n\t coordinator terminates\n"); //terminate coordinate itself
pthread_exit(NULL); //thread ends
}
sem_wait(&student); // waiting for students signal
sem_wait(&mutexLock);
for(int i=0; i<total_student; i++) //find the students who just seated and push them into the
priority queue
{
if(mark_visited[i]>-1)
{
student_priority[i] = total_visit_of_student[i];
arrival_time[i] = mark_visited[i]; //to save the time when the student came
printf("\nCoordinator Thread --> Student-%d with Priority-%d in the queue.\
n",student_id[i],total_visit_of_student[i]);
mark_visited[i]=-1;
sem_post(&coordinator); //notify tutor that student is in the queue.
}
}
sem_post(&mutexLock);
}
}
void *tutor_thread(void *tutor_id)
{
int t_id=*(int*)tutor_id;
while(1)
{
if(student_done==total_student) //if all students finish, tutors threads terminate.
{
sem_wait(&mutexLock);
printf("\n\t tutor-%d terminates\n",t_id);
sem_post(&mutexLock);
pthread_exit(NULL); //thread ends
}
int max_request=total_student*help_limit+1; //this is the maximum serial a student can get
int max_priority = help_limit-1;
int s_id=-1; //it is a flag.
sem_wait(&coordinator); //wait coordinator's notification
sem_wait(&mutexLock);
for(int i=0; i<total_student; i++) //find student with highest priority from priority queue. If
students with same priority, who come first has higher priority
{
if(student_priority[i]>-1 && student_priority[i]<= max_priority)
{
if(arrival_time[i]<max_request)
{
max_priority=student_priority[i];
max_request=arrival_time[i]; //who comes first, here we are trying to find the minimum arrival
time if the priotiy is same
s_id=student_id[i];
}
}
}
if(s_id==-1) //in case no student in the queue.
{
sem_post(&mutexLock);
continue;
}
student_priority[s_id-1] = -1; //reset the priority queue
arrival_time[s_id-1] = -1;
occupied_chair--;
sem_post(&mutexLock);
sem_wait(&mutexLock); //after tutoring
printf("\nTutor Thread --> Student-%d is tutored by Tutor-%d\n",s_id,t_id);
sem_post(&mutexLock);
sem_post(&tutored_student[s_id-1]); //update shared data so student can know who tutored him.
}
}
int main()
{
printf("Total number of students: ");
scanf("%d", &total_student);
printf("Total number of Tutors: ");
scanf("%d", &total_tutor);
printf("Total number of Chairs: ");
scanf("%d", &total_chair);
printf("Maximum number of help a student can get: ");
scanf("%d", &help_limit);
for(int i=0; i<total_student; i++)
{
mark_visited[i]=-1;
student_priority[i] = -1;
arrival_time[i] = -1;
total_visit_of_student[i]=0;
}
sem_init(&student,0,0);
sem_init(&coordinator,0,0);
sem_init(&mutexLock,0,1);
for(int i=0; i<total_student; i++) sem_init(&tutored_student[i],0,0);
pthread_t students[total_student],tutors[total_tutor],coordinator; //allocate threads
for(int i = 0; i < total_student; i++) //create threads for student
{
student_id[i] = i + 1; //saved in array
pthread_create(&students[i], NULL, student_thread, (void*) &student_id[i]);
}
for(int i = 0; i < total_tutor; i++) //create threads for tutors
{
tutor_id[i] = i + 1;
pthread_create(&tutors[i], NULL, tutor_thread, (void*) &tutor_id[i]);
}
pthread_create(&coordinator,NULL,coordinator_thread,NULL); //create thread for coordinator
//join threads, to connect the threads to main program
for(int i =0; i < total_student; i++) pthread_join(students[i],NULL);
for(int i =0; i < total_tutor; i++) pthread_join(tutors[i],NULL);
pthread_join(coordinator, NULL);
}

You might also like