Hey all Heres the prompt for my project question Below is my
Hey all! Here\'s the prompt for my project question. Below is my code which is running with no faults. The issue I am having is when printing the student # it continuously prints \'0\' given the variable p. I can\'t seem to understand why/where the student #0 comes from.
Prompt:
A university computer science department has a teaching assistant (TA) who helps undergraduate students with their programming assignments during regular office hours. The TA’s office is rather small and the TA can help only one student at a time in the office. There are two 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 availlable, the student will come back at a later time. For simplicity we assume there are a total of 4 students, and each student asks for help at most 2 times.
Using C and POSIX threads, mutex locks, and unnamed semaphores, implement a solution that coordinates the activities of the TA and the students. Details for this assignment are provided below.
Use Pthreads to create student threads. 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 one of the chairs 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 sitting on the chairs in the hallway waiting for help. If so, the TA must help each of these students in turn. If no students are present, the TA returns to napping.
To simulate students programming in student threads, and the TA providing help to a student in the TA thread, the appropriate threads should sleep (by invoking sleep() ) for a random period of time (up to 3 seconds). Instead of invoking the random number generator rand() which is not thread-safe, each thread should invoke the thread-safe version rand_r().
1) rand_r() computes a sequence of pseudo-random integers in the range [0, RAND_MAX]. If you want a value between 1 and n inclusive, use (rand_r(&seed) % n) + 1.
2) It is recommended to use a different seed value for rand_r() in each thread so that each thread can get a different sequence of pseudo-random numbers.
My Code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
pthread_mutex_t mutex_lock;
sem_t students_sem;
sem_t ta_sem;
int waiting_students;
#define MAX_SLEEP_TIME 3
#define NUM_OF_STUDENTS 4
#define NUM_OF_HELPS 2
#define NUM_OF_SEATS 2
//Array of all 4 students
int student[NUM_OF_STUDENTS];
//Array of threads for each student
pthread_t students_thread[NUM_OF_STUDENTS];
int ta_sleep = 1;
pthread_t taThread;
//
void* teachersAid(void* arg);
void* studentWork(void* p);
int main(void) {
printf(\"CS149 sleepingTA from Victor Fateh\ \");
//Create Mutex with default attributes
pthread_mutex_init(&mutex_lock, NULL);
//Initialize semaphores for TA and students with initial value 0
sem_init(&ta_sem, 0, 0);
sem_init(&students_sem, 0, 0);
//Create new thread for TA with no arg
//teachersAid() as start routine
pthread_create(&taThread, 0, teachersAid, 0);
//Loop through and create threads for all 4 students
//(students respective thread, no attr, pass student function, student # as argument)
for (int i = 0; i < NUM_OF_STUDENTS; i++){
pthread_create(&students_thread[i], 0, studentWork,(void*) &student[i]);
}
//Loop through all running threads
//Joins to ensure all threads are finished executing
for (int j = 0; j < NUM_OF_STUDENTS; j++){
pthread_join(students_thread[j], NULL);
}
return 0;
}
void* teachersAid(void* p) {
unsigned int myrand = (unsigned int)time(NULL);
rand_r(&myrand);
//Infinite loop
while (1) {
pthread_mutex_lock(&mutex_lock);
ta_sleep = 1;
pthread_mutex_unlock(&mutex_lock);
sem_wait(&students_sem);
printf(\"Helping a student for %d seconds, # of waiting students = %d\ \",MAX_SLEEP_TIME, waiting_students);
sleep(MAX_SLEEP_TIME);
while (waiting_students > 0) {
sem_post(&ta_sem);
pthread_mutex_lock(&mutex_lock);
waiting_students--;
pthread_mutex_unlock(&mutex_lock);
printf(\"Helping a student for %d seconds, # of waiting students = %d\ \",MAX_SLEEP_TIME, waiting_students);
sleep(MAX_SLEEP_TIME);
}
}
return NULL;
}
void* studentWork(void* p) {
int seed = 1;
rand_r(&seed);
int num_help = 0;
int seat_taken = 0;
while (num_help <= NUM_OF_HELPS) {
if (!ta_sleep) {
if (!seat_taken) {
if (waiting_students < NUM_OF_SEATS) {
seat_taken = 1;
pthread_mutex_lock(&mutex_lock);
waiting_students++;
pthread_mutex_unlock(&mutex_lock);
printf(\"Student %d takes a seat, # of waiting student = %d\ \",*(int*) p, waiting_students);
sem_wait(&ta_sem);
seat_taken = 0;
num_help++;
} else {
printf(\"\\tStudent %d programming for %d seconds\ \",*(int*) p, MAX_SLEEP_TIME);
sleep(MAX_SLEEP_TIME);
printf(\"\\tStudent %d will try later\ \", *(int*) p);
}
}
} else if (ta_sleep) {
pthread_mutex_lock(&mutex_lock);
ta_sleep = 0;
pthread_mutex_unlock(&mutex_lock);
sem_post(&students_sem);
sem_wait(&ta_sem);
num_help++;
}
}
printf(\"Student %d is receiving help\ \", *(int*) p);
return NULL;
}
Solution
Answer:
Note: Given code is modified:
Program code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
pthread_mutex_t mutex_lock;
sem_t students_sem;
sem_t ta_sem;
int waiting_students;
int ta_sleep = 1;
#define MAX_SLEEP_TIME 3
#define NUM_OF_STUDENTS 4
#define NUM_OF_HELPS 2
#define NUM_OF_SEATS 2
int stud_id[NUM_OF_STUDENTS];
pthread_t students_thread[NUM_OF_STUDENTS];
pthread_t ta_thread;
void* teachersAid(void* p);
void* studentWork(void* p);
int main (void)
{
int i;
pthread_mutex_init(&mutex_lock, NULL);
sem_init(&ta_sem, 0, 0);
sem_init(&students_sem,0,0);
pthread_create(&ta_thread, 0, teachersAid,0);
for (i = 0; i < NUM_OF_STUDENTS; i++)
pthread_create(&students_thread[i], 0, studentWork,(void*)&stud_id[i]);
for (i = 0; i < NUM_OF_STUDENTS; i++)
pthread_join(students_thread[i], NULL);
pthread_cancel(ta_thread);
printf(\"The TA finished helping all students.\ \");
return 0;
}
void* teachersAid(void* p)
{
rand_r(time(NULL));
while (1)
{
pthread_mutex_lock(&mutex_lock);
ta_sleep = 1;
pthread_mutex_unlock(&mutex_lock);
sem_wait(&students_sem);
printf(\"Helping a student for %d seconds, # of waiting students = %d\", MAX_SLEEP_TIME, waiting_students);
sleep(MAX_SLEEP_TIME);
while (waiting_students > 0)
{
sem_post(&ta_sem);
pthread_mutex_lock(&mutex_lock);
waiting_students--;
pthread_mutex_unlock(&mutex_lock);
printf(\"Helping a student for %d seconds, # of waiting students = %d\", MAX_SLEEP_TIME, waiting_students);
sleep(MAX_SLEEP_TIME);
}
}
return NULL;
}
void* studentWork(void* p)
{
rand_r((unsigned*)1);
int num_help = 0;
int seat_taken = 0;
while (num_help <= NUM_OF_HELPS)
{
if (!ta_sleep)
{
if (!seat_taken)
{
if (waiting_students < NUM_OF_SEATS)
{
seat_taken = 1;
pthread_mutex_lock(&mutex_lock);
waiting_students++;
pthread_mutex_unlock(&mutex_lock);
printf(\"Stdudent %d takes a seat, # of waiting student = %d\", *(int*)p, waiting_students);
sem_wait(&ta_sem);
seat_taken = 0;
num_help++;
}
else
{
printf(\"\\tStudent %d programming for %d seconds\ \",*(int*)p,MAX_SLEEP_TIME);
sleep(MAX_SLEEP_TIME);
printf(\"\\tStudent %d will try later\ \",*(int*)p);
}
}
}
else if (ta_sleep)
{
pthread_mutex_lock(&mutex_lock);
ta_sleep = 0;
pthread_mutex_unlock(&mutex_lock);
sem_post(&students_sem);
sem_wait(&ta_sem);
num_help++;
}
}
printf(\"Student %d is receiving help\", *(int*)p);
return NULL;
}





