jc/md/lp-01/05Trains_presentation1 Threads et Synchronisation Application train Présentation
jc/md/lp-01/05Trains_presentation2 Objectif du chapitre Application des chapitres threads et synchronisation à un exemple concret
jc/md/lp-01/05Trains_presentation3 TRAINS (1) On suppose une voie ferrée unique Des trains doivent passer dans les 2 sens de A vers B et de B vers A On suppose 5 trains en attente de chaque cote 3 trains peuvent se suivre pour emprunter cette voie unique Ecrire le programme qui va gérer le passage de ces 10 trains en toute sécurité
jc/md/lp-01/05Trains_presentation4 TRAINS (2) Comme plusieurs trains peuvent se suivre dans le même sens, il ny a pas exclusion mutuelle entre tous les trains Dans ce cas on utilise la technique des Sémaphores On va créer un sémaphore à 3 jetons De plus pour la sécurité du sens on va créer un événement SENS_AB, et un événement SENS_BA
jc/md/lp-01/05Trains_presentation5 TRAIN (3) Pour quun train puisse entrer sur la voie il lui faudra obtenir lévénement de sens et de plus un des jetons du sémaphore Chaque train sera un thread Il y aura 5 Threads AB_MAIN ( A vers B) Il y aura 5 Threads BA_MAIN ( B vers A) Lors des CreateThread on passera un numéro (1 à 5) pour différencier les 5 Threads de chaque sens, ce qui permet de ne pas écrire le code de 10 threads, mais seulement de 2
jc/md/lp-01/05Trains_presentation6 TRAIN (4) Programme principal –Créer les 10 trains (Threads) –Créer les Event de sens –Créer le sémaphore à 3 jetons possibles –Gérer le passage des trains (2 passages dans chaque sens, ou boucle tant que le dernier train nest pas arrivé: dernier thread non actif) –Fermer tout ce qui a été ouvert (Handle)
jc/md/lp-01/05Trains_presentation7 TRAIN (5) Boucle de gestion des trains –Libérer les jetons –Positionner A vers B pendant 500 ms –Attendre larrivée des trains en récupérant les jetons –Faire la même chose pour lautre sens –Sarrêter quand tous les trains sont passés
jc/md/lp-01/05Trains_presentation8 TRAIN (6) Thread train –Récupérer le numéro du train –Attendre le sémaphore et lévénement de sens –Envoyer message « train numéro x parti » –Attendre 1 seconde (durée du trajet) –Envoyer message « train numéro x arrivé » –Rendre le jeton
jc/md/lp-01/05Trains_presentation9 TRAIN main(1) #include "stdafx.h" #include "Winbase.h" DWORD WINAPI AB_MAIN (LPVOID p); DWORD WINAPI BA_MAIN (LPVOID p); HANDLE SEM; HANDLE SENS_AB,SENS_BA; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
jc/md/lp-01/05Trains_presentation10 TRAIN main(2) // Définitions et réservations // Paramètres passés aux threads valeurs de 1 à 5 // TODO // HANDLE utilisés // TODO printf("début du main\n\r\n"); // Création d'un sémaphore à 3 jetons possibles // vide au départ // TODO
jc/md/lp-01/05Trains_presentation11 TRAIN main(3) // Création des événements de sens // TODO // Création des 10 Threads // TODO
jc/md/lp-01/05Trains_presentation12 TRAIN main(4) // Boucle principale do { // Attente avant départ de A vers B (1 seconde) // TODO // Libération des 3 jetons // TODO // Set de l'Event de sens de A vers B // TODO // Attente de 500 tics ( demi seconde) // TODO // Reset de l'Event de sens de A vers B // TODO
jc/md/lp-01/05Trains_presentation13 TRAIN main(4) // Attente de l'arrivée des trains // Récupération des 3 jetons // TODO // Attente avant départ de B vers A (1 seconde) // TODO // Libération des 3 jetons // TODO // Set de l'Event de sens de B vers A // TODO // Attente de 500 tics // TODO // Reset de l'Event de sens de B vers A // TODO
jc/md/lp-01/05Trains_presentation14 TRAIN main(5) // Attente de l'arrivée des trains // Récupération des 3 jetons // TODO // Vérification de l'arrivée du dernier train // TODO } while // Fin de boucle // TODO
jc/md/lp-01/05Trains_presentation15 TRAIN main(6) printf ("fin du main"); getchar(); // Close des Handle // TODO return 0; }
jc/md/lp-01/05Trains_presentation16 TRAIN ThreadA_B (1) DWORD WINAPI AB_MAIN (LPVOID p) { // Initialisation des variables de retour // de la fonction WaitForSingleObject DWORD SENS=1,SEMA=1; // Récupération du numéro du thread (DWORD pp) // p est un pointeur de void // il pointe sur le paramètre passé au thread // TODO
jc/md/lp-01/05Trains_presentation17 TRAIN ThreadA_B (2) // Attente de l'obtention du sens et du sémaphore // les 2 valeurs doivent être égales a zéro // TODO // Traitement printf ("départ du train AB %d \n\r",pp); Sleep (1000); printf ("arrivée du train AB %d \n\r",pp); // Libération du sémaphore // TODO return 0; }
jc/md/lp-01/05Trains_presentation18 TRAIN ThreadB_A (1) DWORD WINAPI BA_MAIN (LPVOID p) { // Initialisation des variables de retour // de la fonction WaitForSingleObject DWORD SENS=1,SEMA=1; // Récupération du numéro du thread (DWORD pp) // p est un pointeur de void // il pointe sur le paramètre passé au thread // TODO
jc/md/lp-01/05Trains_presentation19 TRAIN ThreadB_A (2) // Attente de l'obtention du sens et du sémaphore // les 2 valeurs doivent être égales a zéro // TODO // Traitement printf ("départ du train BA %d \n\r",pp); Sleep (1000); printf ("arrivée du train BA %d \n\r",pp); // Libération du sémaphore // TODO return 0; }
jc/md/lp-01/05Trains_presentation20 Résultat
jc/md/lp-01/05Trains_presentation21 Conclusion Une bonne utilisation des sémaphores et des événements permet dobtenir lenchaînement désiré