But de l’application
L’application consiste à créer trois threads et à les faire communiquer en utilisant une FIFO thread-safe.
Le premier thread
charge le contenu d’un fichier texte et envoie les caractères lus dans une FIFO.
Le second thread
récupère les caractères présents dans la première FIFO et convertit les caractères minuscules en majuscule puis les envoie dans une seconde FIFO.
Le troisième thread
est chargé de récupérer les caractères de la seconde FIFO et de les afficher à l’écran.
Organisation du code

Le programme comporte un fichier
qui contient les corps de 3 fonctions
1
| LireFichier(); calculer(); et afficher(); |
qui vont constituer nos threads.
Les fichiers
contiennent les déclarations et les corps des fonctions utilisés par notre FIFO circulaire thread-safe.
Le thread
ouvre un fichier texte, et enfile les caractères lus dans la FIFO jusqu’à la fin du fichier. Lorsque un caractère ne peut pas être enfilé, il sera à nouveau enfilé lors de l’occurrence suivante de la boucle. Lorsque la fin du fichier est atteint, le thread enfile un caractère « null » pour signaler la fin du fichier.
Le thread
défile les caractères contenus dans la FIFO, convertit les caractères minuscules en majuscule et les enfile dans la seconde FIFO. Lorsque le thread rencontre un caractère « null », il l’enfile puis se termine.
Le thread
défile les caractères contenus dans le seconde FIFO et les affiche à l’écran. Lorsqu’il rencontre le caractère « null », il se termine.
Notre structure s_file est une file circulaire doublement chaînée dans un tableau. Elle comporte un tableau de caractères, un pointeur de tête et un pointeur de queue. Un mutex permet de délimiter les sections critiques et deux sémaphores sont utilisées comme compteur d ‘entrée et compteur de sortie qui vont permettre de limiter le contenu de la file.
La fonction
initialise le sémaphore sem_f avec la valeur de la taille de la file. Le sémaphore sem_e est initialisé à 0. Le mutex et les pointeurs de tête et de queue sont aussi initialisés par cette fonction.
La fonction
enfile un caractère. Le sémaphore sem_f est décrémenté à chaque appel. Lorsque la file est pleine, la valeur du sémaphore est nulle et la thread est bloquée. Ceci empêche la file de se remplir au delà de sa taille. L’ajout du caractère dans la file et la modification des pointeurs de tête et de queue sont effectués dans une section critique protégée par le mutex afin que plusieurs modifications simultanées ne soient pas possibles. Ensuite, le sémaphore sem_e est incrémenté. Ce qui va permettre d’indiquer que la file contient des caractères. Finalement, le mutex est débloqué et le thread se termine.
La fonction
défile un caractère. Le sémaphore sem_e est décrémenté lorsque un caractère est défilé et bloque le thread lorsque la file est vide. La lecture et la modification des pointeurs de file sont réalisées dans une section critique protégée par le mutex. La valeur est retournée et le sémaphore sem_f est incrémenté. Le mutex est libéré et le thread se termine.

Diagramme temporel de sem_e

Diagramme temporel de sem_f
Rappel sur les types de sémaphores :
- Sémaphore binaire : Il est initialisé à 0 et permet de synchroniser deux threads. En effet, une instruction
va interrompre le thread. L’instruction
dans un autre thread va libérer le thread interrompu. Nous utilisons un sémaphore binaire sem_e.
- Sémaphore utilisé comme mutex : Il est initialisé à 1 il se comporte comme un mutex.
Une instruction
débute une section critique et une instruction
la termine. Nous n’utilisons pas ce type de sémaphore dans notre programme mais nous utilisons un mutex.
- Sémaphore utilisé comme compteur : Il est initialisé à une valeur N supérieure à 1. Il protège l’accès à une ressource de taille N. Nous utilisons ce type de sémaphore afin de protéger notre FIFO.
Nous utilisons ici un sémaphore binaire sem_e initialisé à 0.
1 2
| sem_t sem_e; //déclaration
sem_init(&t->sem_e,0,0); //initialisation |
Ce sémaphore va empêcher que le thread défile un caractère lorsque la file est vide. Il est incrémenté à chaque ajout de caractères dans la file.