philosophers_prep/rendu/limited_resources.c

110 lines
3.3 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* limited_resources.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: ruiferna <ruiferna@student.42porto.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/10/08 19:31:58 by ruiferna #+# #+# */
/* Updated: 2025/10/09 10:25:31 by ruiferna ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#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);
}