-
Homepage
-
Accurate POSIX Programming Project Help in C
PROBLEM.
Consider a university professor that helps students with some programming tasks at office hours only. He has a small office with room for just one desk carrying one chair and computer. Outside the office is a hallway with three chairs on which students sit while waiting for the professor to sort another student. The professor takes a nap if there aren’t any students that need help during office hours. If a student comes for help during office hours and the professor is taking a nap, s/he must first awaken the professor before asking for help. If a student arrives and finds the professor currently helping another student, the student sits on one of the chairs in the hallway and waits. If a student comes and gets that the professor is still helping another student, s/he must sit on the chairs in the hallway and wait; if there aren’t any chairs available, the student must go back and return at a later time.
From the description of the problem, we will use semaphores (https://en.wikipedia.org/wiki/Semaphore_(programming)) and implement two threads;
1. studentsThd() - which can either get tutored or will leave if there is no free chair
2. professorThd() – a single thread which can either tutor students or go to sleep
Here, the professor indicates the operating system, and the students are the processes. The operating system needs to allocate the needed resources to the processes while avoiding any deadlock. There are many various solutions to this problem, so be sure to follow the provided guidance.
Project:
Implement the Sleeping professor problem in C.
Solution
#include
#include
#include
#include
#include
#include
#include
#define STUDENT_COUNT_MIN 2
#define STUDENT_COUNT_MAX 10
#define CHAIR_COUNT 3
#define HELPS_MAX 3
pthread_mutex_t chairsMutex = PTHREAD_MUTEX_INITIALIZER;
sem_t studentSem;
sem_t profSem;
sem_t chairsSem[CHAIR_COUNT];
int *studentHelpCounts;
int numStudents = 0;
int usedChairs = 0;
int helpsLeft = 0;
// Professor thread
void *professor(void *args)
{
bool awake = false;
while(helpsLeft > 0)
{
sem_wait(&profSem);
if(!awake)
{
printf("\033[0;92mProfessor has been awakened by a student.\033[0m\n");
awake = true;
}
// Signal the student to come in
pthread_mutex_lock(&chairsMutex);
sem_post(&chairsSem[--usedChairs]);
pthread_mutex_unlock(&chairsMutex);
printf("\033[0;92mStudent frees chair and enters professors office. Remaining chairs %d\033[0m\n", CHAIR_COUNT - usedChairs);
// Student comes in and get the help
printf("\033[0;92mProfessor is helping a student.\033[0m\n");
usleep(rand() % 1500000);
// Done helping student
sem_post(&studentSem);
helpsLeft--;
}
return (void *)NULL;
}
// Student thread
void *student(void *args)
{
int *studentId = (int *)args;
while(studentHelpCounts[*studentId] > 0)
{
// Work on an assignment
printf("\033[;93mStudent %d doing assignment.\033[0m\n", (*studentId) + 1);
usleep(rand() % 2000000);
// Ask for help
if(usedChairs >= CHAIR_COUNT)
{
printf("\033[0;31mChairs occupied, student %d will return later.\033[0m\n", (*studentId) + 1);
}
else
{
printf("\033[0;31mStudent %d needs help from the professor.\033[0m\n", (*studentId) + 1);
// Occupy a chair
int chairIndex;
pthread_mutex_lock(&chairsMutex);
chairIndex = usedChairs;
usedChairs++;
pthread_mutex_unlock(&chairsMutex);
// Wait until professor is available to help
sem_post(&profSem);
sem_wait(&chairsSem[chairIndex]);
// Vacate the chair
printf("\033[0;31mStudent %d is getting help from the professor.\033[0m\n", (*studentId) + 1);
// Wait until professor is done helping
sem_wait(&studentSem);
// Done, stop if no more help needed
studentHelpCounts[*studentId]--;
}
}
free(studentId);
return (void *)NULL;
}
// Entry point of the program
int main(int argc, char *argv[])
{
// Initialize the number of students
while(true)
{
printf("How many students coming to professor's office? ");
scanf("%d", &numStudents);
if(numStudents >= STUDENT_COUNT_MIN && numStudents <= STUDENT_COUNT_MAX)
break;
}
// Initialize the number of helps each student needs
studentHelpCounts = (int *)malloc(sizeof(int) * numStudents);
for(int i = 0; i < numStudents; i++)
{
int numHelps = rand() % HELPS_MAX + 1;
studentHelpCounts[i] = numHelps;
helpsLeft += numHelps;
}
// Initialize the student threads
pthread_t *studentsThread = (pthread_t *) malloc(sizeof(pthread_t) * numStudents);
// Initialize the semaphores
sem_init(&profSem, 0, 0);
sem_init(&studentSem, 0, 0);
for(int i = 0; i < CHAIR_COUNT; i++)
sem_init(&chairsSem[i], 0, 0);
// Create the professor thread
pthread_t profThread;
pthread_create(&profThread, NULL, &professor, NULL);
// Create the student threads
for(int i = 0; i < numStudents; i++)
{
int *studentId = (int *)malloc(sizeof(int));
*studentId = i;
pthread_create(&studentsThread[i], NULL, &student, studentId);
}
// Wait for appropriate threads to complete
for(int i = 0; i < numStudents; i++)
pthread_join(studentsThread[i], NULL);
pthread_join(profThread, NULL);
// Clean up
free(studentsThread);
free(studentHelpCounts);
return 0;
}