1 Introduction
Dans ce deuxième TP nous allons aborder les outils fournis avec la librarie pthread pour assurer les
accès aux ressources partagées. Ces outils sont les sémaphores et les mutex (mutal exclusions). Pour
illustrer leurs utilisations, nous allons nous servir de l’algorithme du producteur/consommateur.
2 Un buffer circulaire
Un unique producteur (aussi appelé écrivain) et un unique consommateur (aussi appelé client ou
lecteur) partage un buffer circulaire stockant des valeurs entières.
#include <stdio.h>
#include <pthread.h>
#define BUFFER_SIZE 16
// Initialise le buffer
void init(struct prodcons * b)
{
// sémaphore équivalent au empty
sema_init(&b->sem_write, BUFFER_SIZE - 1, NULL, NULL );
b->readpos = 0;
b->writepos = 0;
}
1
// écriture d’un entier dans le buffer
void put(struct prodcons * b, int data)
{
// attendre que le buffer ne soit plus plein
sema_wait( &b->sem_write ); // down(&empty)
return data;
}
2
return NULL;
}
while (1) {
d = get(&buffer);
if (d == OVER) break;
printf("---> %d\n", d);
}
return NULL;
}
int main(void)
{
pthread_t th_a, th_b;
void * retval;
init(&buffer);
return 0;
}
#include <stdio.h>
#include <pthread.h>
// Les constantes
#define OVER (-1)
3
#define EMPTY (-2)
#define NBITEM 5
#define NBCL 3 // nbre de clients
#define NBPD 3 // nbre de producteurs
// la strucuture partagée
typedef struct prodcons {
int word ; // la mémoire partagée
int consid ; // numero du client (>= 0)
pthread_mutex_t exclu; // la variable de mutex
} str_prodcons;
// la variable partagée
static str_prodcons buffer;
return modif ;
4
}
int data ;
return data ;
}
return NULL ;
}
5
void *consumer( void * data ) {
int word,
i=0,
num = (int) data,
cb = 0 ; // compteur d’OVER
char c ;
return NULL;
}
int main(void) {
6
pthread_join( th_a[prodid], NULL ) ;
for( clientid=0; clientid<NBCL; clientid++ )
pthread_join( th_b[clientid], NULL) ;
return 0;
}
4 Exercices
1. Plusieurs producteurs et plusieurs consommateurs partagent un buffer circulaire
2. Écrire la solution des lapins et des renards. Les threads concernent uniquement les fonctions
lapin(i) et renard(i). Les algorithmes Parent Renard(r), Parent Lapins(l) et Grand Parent(r,l)
restent sous forme de processus.