PB Philosophes
PB Philosophes
PB Philosophes
Introduction : N philosophes (ici 5) sont assis a une table circulaire, ils aimeraient manger leur plat
de spaghettis avec 2 fourchettes chacun mais il n'y a que N fourchettes. Evidemment ils ne pourront
pas tous manger en même temps. Il s'agit d'écrire un outil de synchronisation pour ce problème.
Philo(i){
while(1){
pense( );
prendre_fourchette( i );
manger ( );
poser_fourchette( i );
}
}
prendre_fourchette ( int i ){
fourch[ i ].P( ); //demande/prend de la fourchette de gauche
fourch[ (i + 1) % N ].P( ); //demande/prend la fourchette de droite
}
poser_fourchette ( int i ){
fourch[ i ].V( ); //pose de la fourchette de gauche
fourch[ (i + 1) % N ].V( ); //pose la fourchette de droite
}
Cette implémentation pose un problème d'interblocage dans le cas où les N philosophes décident de
manger donc d'appliquer la procédure prendre fourchette. En effet, tous les philosophes détiennent
la fourchette qui est à leur droite et attendent que celle qui est a leur gauche se libère.
Deuxième solution :
On se centre ici sur les philosophes. Un sémaphore est attribué à chaque philosophe.
Etat = { PENSE , MANGE , A_FAIM}
Un philosophe qui veut prendre les fourchettes (donc manger) déclare qu'il a faim. Si l'un de ses
deux voisins est en train de manger, il ne peut donc pas prendre les deux fourchettes pour l'instant et
donc se met en attente. Si les deus philosophes a coté ne mangent pas alors il peut prendre les deux
fourchettes et déclarer qu'il mange. Quand le philosophe a fini de manger, il déclare donc qu'il
pense et regarde si ses deux voisins qui forcément ne pouvaient pas manger, en ont dès lors
l'opportunité. Si c'est le cas il les réveille.
sem philo_prive [ N ]
Etat Etat_Philo[ N ] = { PENSE, …......., PENSE}
sem mutex = 1 //mutex.c = 1 pour que l'écriture dans le tableau Etat_Philo se
//fasse en exclusion mutuelle
test_mange( int i ){
if (Etat_Philo[ i ] == A_FAIM
&& Etat_Philo[ (i+1)%N ] != MANGE
&& Etat_Philo[ (i-1+N)%N ] != MANGE ) {
Etat_Philo[ i ] = MANGE;
philo_prive[ i ].V( );
}
}
prendre_fourchette ( int i ){
if ( i == N-1) { // N-1 : le philosophe gaucher
fourch[ (i + 1) % N ].P( );
fourch[ i ].P( );
}
else{
fourch[ i ].P( ); //demande/prend de la fourchette de gauche
fourch[ (i + 1) % N ].P( ); //demande/prend la fourchette de droite
}
}
poser_fourchette ( int i ){
fourch[ i ].V( ); //pose de la fourchette de gauche
fourch[ (i + 1) % N ].V( ); //pose la fourchette de droite
}
Quatrième solution :
On modifie la solution 1 de sorte que les philosophes ne puissent pas prendre tous en même temps
la fourchette de droite.
On introduit pour cela un sémaphore dont le compteur est égal à N-1
sem s = N-1;
prendre_fourchette ( int i ){
s.P( );
fourch[ i ].P( ); //demande/prend de la fourchette de gauche
fourch[ (i + 1) % N ].P( ); //demande/prend la fourchette de droite
s.V( );
}
file_privee[ i ].wait( );
}
Etat_Philo = MANGE;
}
poser_fourchette ( int i ){
if ( Etat_Philo[ (i+2)%N ] == PENSE ) { //si le philosophe de droite a
//l'opportunité de manger