/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* limited_resources.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: ruiferna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/10/08 19:31:58 by ruiferna #+# #+# */ /* Updated: 2025/10/09 10:25:31 by ruiferna ### ########.fr */ /* */ /* ************************************************************************** */ #include #include #include #include #include #include #include #define STUDENTS 10 /* - 3 computers (limited access) - Only 3 students can use the PC at same time - Implement a "semaphore" (using mutex, counter and condictions) */ typedef struct s_shared { int pcs_available; int students; pthread_mutex_t pcs_available_mutex; pthread_mutex_t students_mutex; } t_shared; void *student_routine(void *arg) { /* Print when students: - Arrive at the library - Get a computer - Finish using the computer - Leave the library */ t_shared *shared; int student_id; shared = (t_shared *) arg; /* Use a reentrant RNG (rand_r) with a per-thread seed to avoid data races when using rand()/srand() from multiple threads. */ unsigned int seed = (unsigned int)time(NULL) ^ (unsigned int)(unsigned long)pthread_self(); pthread_mutex_lock(&shared->students_mutex); shared->students += 1; student_id = shared->students; printf("[%i] Student %i arrived at the library.\n", student_id, student_id); pthread_mutex_unlock(&shared->students_mutex); while (1) { pthread_mutex_lock(&shared->pcs_available_mutex); if (shared->pcs_available > 0) { shared->pcs_available -= 1; printf("[%i] Student %i got a computer.\n", student_id, student_id); pthread_mutex_unlock(&shared->pcs_available_mutex); break; } else { pthread_mutex_unlock(&shared->pcs_available_mutex); usleep(100); } } int use_time = 2 + (rand_r(&seed) % 4); usleep(use_time * 1000000); pthread_mutex_lock(&shared->pcs_available_mutex); shared->pcs_available += 1; printf("[%i] Student %i finished using a computer.\n", student_id, student_id); pthread_mutex_unlock(&shared->pcs_available_mutex); printf("[%i] Student %i left the library.\n", student_id, student_id); return (NULL); } int main() { pthread_t *students; t_shared shared; shared.pcs_available = 3; shared.students = 0; pthread_mutex_init(&shared.pcs_available_mutex, NULL); pthread_mutex_init(&shared.students_mutex, NULL); students = (pthread_t *) malloc (sizeof(pthread_t) * STUDENTS); int i = 0; while (i < STUDENTS) { pthread_create(&students[i], NULL, student_routine, &shared); i++; } i = 0; while (i < STUDENTS) { pthread_join(students[i], NULL); i++; } pthread_mutex_destroy(&shared.pcs_available_mutex); pthread_mutex_destroy(&shared.students_mutex); free(students); return (0); }