jc/md/lp-01/05Trains_corrigé1 Threads et Synchronisation Application train Corrigé
jc/md/lp-01/05Trains_corrigé2 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_corrigé3 TRAIN main(2) // Définitions et réservations // Paramètres passés aux threads valeurs de 1 à 5 DWORD ThPa1 = 1; DWORD ThPa2 = 2; DWORD ThPa3 = 3; DWORD ThPa4 = 4; DWORD ThPa5 = 5; DWORD val; // HANDLE utilisés HANDLE AB_11, AB_12, AB_13, AB_14, AB_15, BA_21, BA_22, BA_23, BA_24, BA_25;
jc/md/lp-01/05Trains_corrigé4 TRAIN main(3) // Création d'un sémaphore à 3 jetons possibles // vide au départ SEM=CreateSemaphore(NULL,0,3,NULL); // Création des événements de sens SENS_AB=CreateEvent(NULL,TRUE,FALSE,NULL); SENS_BA=CreateEvent(NULL,TRUE,FALSE,NULL); printf("début du main\n\r\n");
jc/md/lp-01/05Trains_corrigé5 TRAIN main(4) // Création des 10 Threads AB_11=CreateThread( 0, 0, AB_MAIN, &ThPa1, 0, 0); AB_12=CreateThread( 0, 0, AB_MAIN, &ThPa2, 0, 0); AB_13=CreateThread( 0, 0, AB_MAIN, &ThPa3, 0, 0); AB_14=CreateThread( 0, 0, AB_MAIN, &ThPa4, 0, 0); AB_15=CreateThread( 0, 0, AB_MAIN, &ThPa5, 0, 0); BA_21=CreateThread( 0, 0, BA_MAIN, &ThPa1, 0, 0); BA_22=CreateThread( 0, 0, BA_MAIN, &ThPa2, 0, 0); BA_23=CreateThread( 0, 0, BA_MAIN, &ThPa3, 0, 0); BA_24=CreateThread( 0, 0, BA_MAIN, &ThPa4, 0, 0); BA_25=CreateThread( 0, 0, BA_MAIN, &ThPa5, 0, 0);
jc/md/lp-01/05Trains_corrigé6 TRAIN main(5) // Boucle principale do { // Attente avant depart de A vers B Sleep(1000); //Libération des 3 jetons ReleaseSemaphore(SEM,3,NULL); //Set de l'Event de sens de A vers B SetEvent(SENS_AB); //Attente de 500 tics Sleep (500); //Reset de l'Event de sens de A vers B ResetEvent(SENS_AB);
jc/md/lp-01/05Trains_corrigé7 TRAIN main(6) // Attente de l'arrivée des trains // et récupération des 3 jetons WaitForSingleObject(SEM,INFINITE); // Attente avant départ de B vers A Sleep(1000); //Libération des 3 jetons ReleaseSemaphore(SEM,3,NULL);
jc/md/lp-01/05Trains_corrigé8 TRAIN main(7) // Set de l'Event de sens de B vers A SetEvent(SENS_BA); // Attente de 500 tics Sleep (500); // Reset de l'Event de sens de B vers A ResetEvent(SENS_BA); // Attente de l'arrivée des trains // et récupération des 3 jetons WaitForSingleObject(SEM,INFINITE);
jc/md/lp-01/05Trains_corrigé9 TRAIN main(8) // Vérification de l'arrivée du dernier train GetExitCodeThread ( BA_25,&val); printf ("code du thread : %d \n\r", val); } //Continuer tant que dernier train pas arrivé while ( val == 259 ) ; printf ("fin du main"); getchar();
jc/md/lp-01/05Trains_corrigé10 TRAIN main(10) // Close des Handle CloseHandle(AB_11); CloseHandle(AB_12); CloseHandle(AB_13); CloseHandle(AB_14); CloseHandle(AB_15); CloseHandle(BA_21); CloseHandle(BA_22); CloseHandle(BA_23); CloseHandle(BA_24); CloseHandle(BA_25);
jc/md/lp-01/05Trains_corrigé11 TRAIN main(11) CloseHandle(SEM); CloseHandle(SENS_AB); CloseHandle(SENS_BA); return 0; }
jc/md/lp-01/05Trains_corrigé12 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 DWORD pp= *(DWORD*) p;
jc/md/lp-01/05Trains_corrigé13 TRAIN ThreadA_B (2) // Attente de l'obtention du sens et du sémaphore // les 2 valeurs doivent être égales a zéro while ( SENS!=0 || SEMA!=0) { SENS=WaitForSingleObject(SENS_AB,INFINITE); SEMA=WaitForSingleObject(SEM,1); }
jc/md/lp-01/05Trains_corrigé14 TRAIN ThreadA_B (3) // 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 ReleaseSemaphore(SEM,1,NULL); return 0; }
jc/md/lp-01/05Trains_corrigé15 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 DWORD pp= *(DWORD*) p;
jc/md/lp-01/05Trains_corrigé16 TRAIN ThreadB_A (2) // Attente de l'obtention du sens et du sémaphore // les 2 valeurs doivent être égales a zéro while ( SENS!=0 || SEMA!=0) { SENS=WaitForSingleObject(SENS_BA,INFINITE); SEMA=WaitForSingleObject(SEM,1); }
jc/md/lp-01/05Trains_corrigé17 TRAIN ThreadB_A (3) // 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 ReleaseSemaphore(SEM,1,NULL); return 0; }
jc/md/lp-01/05Trains_corrigé18 Résultat