TP Synchronisations - Mutex - Sémaphores
On the road once again.
Comme le nom du TP l’indique, vous allez utiliser des verrous (mutex) et les sémaphores pour synchroniser les threads en charge de faire avancer des voitures. Le but est que les voitures se croisent sans collision.
Vous pouvez télécharger une version PDF de ce sujet.
Attendu
Vous avez deux séances pour ce TP.
Fourni
Pour ce TP, vous partirez de l’exemple fourni dans le fichier
stillOnTheRoad.c.
Le programme fourni crée des voitures dans les deux sens et les fait avancer. Vous remarquerez que les collisions entre voitures sont signalées en rouge.
Comme pour le TP précédent, référez-vous à la page dédiée à la bibliothèque libroad pour la mise en place et la documentation.
1. Passage d’une seule voiture à la fois
La première étape va consister à faire en sorte qu’une seule voiture ne passe dans la voie réduite à la fois. Pour cela vous allez utiliser un mutex.
1.1. Création d’un mutex partagé
Vous passerez à un fichier stillOnTheRoadQ1.1.c pour cette question.
Lorsque l’on utilise les threads POSIX, un mutex est de type pthread_mutex_t et on l’initialise à
l’aide de la macro PTHREAD_MUTEX_INITIALIZER. Ce qui donne :
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
En utilisant un mutex, la fonction road_distToCross et la constante
road_minDist, faites en sorte qu’une voiture ne tente de passer le
croisement que si elle parvient à obtenir le mutex.
Attention : un thread qui tente de faire un "lock" sur un mutex qu’il a déjà "locké" sera bloqué indéfiniment.
Il vous faudra donc prendre soin de :
-
ne prendre le mutex qu’une fois par passage de la voiture et
-
bien penser à libérer le mutex en sortie de croisement.
Les voitures ne doivent plus entrer en collision dans le croisement. En revanche, pour cette question, il est normal qu’elles entrent en collision dans la file d’attente.
1.2. Éviter les collisions dans la file
Vous passerez à un fichier stillOnTheRoadQ1.2.c pour cette question.
Utilisez la fonction road_distNextCar pour faire en sorte que les voitures n’avancent pas
si elles sont trop près de la voiture qui les précède.
Il est fortement suggérer de créer une fonction qui encapsule l’appel à road_stepCar pour ne faire avancer la voiture que si elle peut le faire sans collision.
2. Passage de plusieurs voitures dans le même sens
Vous passerez à un fichier stillOnTheRoadQ2.c pour cette question.
Afin de permettre à plusieurs voitures d’être sur la voie rétrécie simultanément, vous allez utiliser deux sémaphores, un par voie. Chacun de ces sémaphores peut être vu comme un feu de circulation.
Pour simplifier la synchronisation de ces feux, celle-ci sera effectuée par un thread à part qui s’occupera de bloquer un des sémaphores de voie, puis l’autre à intervalle régulier.
Vous aurez besoin des fonctions vues en cours :
-
sem_initpour initialiser les sémaphores de voie; -
sem_waitet -
sem_post.
Il est suggéré de faire une fonction switchLanes qui se charge de bloquer le
sémaphore de la voie qui est libre puis de libérer le sémaphore de celle qui
bloquée. Cette fonction sera appelée à intervalle régulier dans un thread autonome.
2.1. S’il vous reste du temps
S’il vous reste du temps, faites en sorte que le changement de voie se fasse sur réception d’un signal et non plus de manière automatique. Vous utiliserez SIGALRM et/ou SIGINT.
La réponse éventuelle à cette question se fera dans un nouveau fichier stillOnTheRoadQ4.c.
Vous avez deux séances pour réaliser ce TP.