efrei/programmation-multitaches-temps-reel/philosophes/philosophe.c

87 lines
1.9 KiB
C

/* Structure d'un philosophe :
Var semaphore test;
Repeat
wait(test);
prendre baguettes si possible;
signal(test);
manger;
lacher baguettes;
penser;
Until false;
=> Seule la prise de baguettes est sérialisée.
=> Problème si beaucuoup de philosophes.
*/
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#define N 5 // nombre de philosophes
#define G ((N + i - 1) % N) // philosophe de gauche de i
#define D ((N + i + 1) % N) // philosophe de droite de i
enum etat {penser, faim, manger} ;
enum etat Etat [N] = {penser, penser, penser, penser, penser};
sem_t S [N] ;
sem_t mutex ;
void *philosophe(void *);
void Test(int i);
int main () {
int i , NumPhi[N] = {0, 1, 2, 3, 4};
pthread_t ph[N] ;
srand(time(NULL));
sem_init(&mutex, 0, 1);
for (i = 0; i < N; i++)
sem_init(&S[i], 0, 0);
for (i = 0; i < N; i++)
pthread_create(&ph[i], NULL, philosophe, &(NumPhi[i]));
// attendre la fin des threads
for (i = 0; (i < N && pthread_join(ph[i], NULL) == 0); i++);
printf("fin des threads\n");
return 0;
}
void *philosophe(void *num) {
int i =* (int*) num;
int nb = 2;
while (nb) {
nb--;
sleep(rand() % 3 + 1); // penser
sem_wait(&mutex); // tenter de manger
Etat[i] = faim;
Test(i);
sem_post(&mutex);
sem_wait(&S[i]);
printf("philosophe [%d] mange\n", i); // manger
sleep(rand() % 3 + 1);
printf("philosophe [%d] a fini de manger\n", i);
// libérer les fourchettes
sem_wait(&mutex);
Etat[i] = penser;
Test(G); Test(D);
sem_post(&mutex);
}
return num;
}
void Test(int i) {
if ((Etat[i] == faim) && (Etat[G] != manger) && (Etat[D] != manger)) {
Etat[i] = manger;
sem_post(&S[i]);
}
}