Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application...

45
jc/md/lp-01/06 Threads 1 Threads

Transcript of Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application...

Page 1: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 1

Threads

Page 2: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 2

Objectif du chapitre

• Génération d’une application avec thread– Création d’un thread– Identification d’un thread– Suspension/Reprise d’un thread– Destruction d’un thread– Contrôle de l’exécution

• Exemples de threads

Page 3: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 3

Point de départ

• Partir d’une plate-forme de base pour émulateur de type « Industrial Controller »

• Construire (Build) la plate-forme

• Créer une application THREAD1 de type « Simple Windows CE Application »

Page 4: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 4

Création de l’application

Page 5: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 5

Application THREAD1

Page 6: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 6

Platform Settings

Page 7: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 7

Création d’un thread (1)

Fonction CreateThread

HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);

Valeur de retour : handle créé ou NULL

Page 8: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 8

Création d’un thread (2) : arguments

lpThreadAttributes : NULL sous CE,

dwStackSize : taille de la pile du thread créé

lpStartAddress : pointeur sur le début du thread

lpParameter : pointe une variable pour le thread

dwCreationFlags : 0 pour démarrer le thread

lpThreadId : pointeur sur une variable qui reçoit l’identificateur de thread, le ThreadId

Page 9: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 9

Suspend/Resume Thread

• Gestion du compteur associé au thread• Thread éligible quand ce compteur est nul• Pour suspendre un thread

DWORD SuspendThread( HANDLE hThread );La fonction incrémente le compteur de mise en sommeil et retourne la valeur du compteur.

• Pour redémarrer un threadDWORD ResumeThread( HANDLE hThread );La fonction décrémente le compteur de mise en sommeil et retourne la valeur du compteur.

Page 10: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 10

Fin d’un thread• Pour terminer proprement un thread, le mieux

est d’utiliser la fonction ExitThread VOID ExitThread(DWORD dwExitCode);• Le code de sortie est récupérable par celui qui a

créé le thread par la fonction :BOOL GetExitCodeThread(

HANDLE hThread,

LPDWORD lpExitCode);

• L’appelant devra ensuite fermer le handle

Page 11: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 11

Application THREAD1

• L’application va créer un thread qui sera suspendu par la fonction Sleep

• La durée de la suspension est fixée par le paramètre fourni par CreateThread

• On vérifiera– Que le thread est actif en testant le code de retour

259 en décimal– Puis qu’il se termine en renvoyant un code de sortie

différent, par exemple 12345678

• Enfin, CloseHandle ferme le handle

Page 12: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 12

Génération de l’application

• Fonction main THREAD1.cpp– Ouverture du fichier– Insertion du code de main

• Fonction A_MAIN– Insertion d’un nouveau fichier THREAD1fonc.cpp

dans le projet– Ouverture du fichier– Insertion du code de la fonction

• Compilation des fichiers .cpp• Génération de l’exécutable .exe

Page 13: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 13

Ouverture de THREAD1.cpp

Onglet FileView

Page 14: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 14

THREAD1 main (1)

#include "stdafx.h "#define ATTENTE 1000void WINAPI A_MAIN(LPDWORD p); //déclaration fonctionint WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){

HANDLE hFils;DWORD argument_pour_le_fils; //pour l’exempleDWORD thread_fils_Id=0;LPDWORD lpThreadFilsId=&thread_fils_Id;DWORD code_mis_par_le_fils;

Page 15: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 15

THREAD1 main (2)

printf("WinMain: début du thread primaire de THREAD1\n");

argument_pour_le_fils=ATTENTE //en ms

//Création du thread fils

hFils=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)A_MAIN,&argument_pour_le_fils,0,lpThreadFilsId);

Page 16: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 16

THREAD1 main (3)

do //boucle d’attente de la fin du thread fils

{GetExitCodeThread(hFils,&code_mis_par_le_fils); //code actualisé à chaque passage

printf("WinMain: code de retour du thread fils: %d\n",code_mis_par_le_fils);

Sleep(400); //on redonne la main au système

}

while(code_mis_par_le_fils == STILL_ACTIVE);

Page 17: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 17

THREAD1 main (4)

printf("WinMain: fin de la boucle d'attente\n");printf("WinMain: code de retour du thread fils :

%d\n",code_mis_par_le_fils);CloseHandle(hFils);printf("WinMain: fin du thread primaire (main de THREAD1)\n");getchar(); //attente d'un caractère pour

maintenir la fenêtre ouvertereturn 0;

}

Page 18: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 18

Insertion d’un fichier dans le projet

Page 19: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 19

Type et nom du fichier inséré

Page 20: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 20

Ouverture du nouveau fichier

Page 21: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 21

Insertion du code de A_MAIN

// THREAD1fonc.cpp #include "stdafx.h" //indispensable avec l'option /Yu du compilateur

void WINAPI A_MAIN(LPDWORD pAdresse_argument){

DWORD attente; //utilisée pour une meilleure clartéprintf("A_MAIN: début du thread fils\n");attente=*pAdresse_argument; //récupération de l’argumentprintf("A_MAIN: argument envoyé par WinMain= %d\n",attente);Sleep(attente);printf("A_MAIN: fin du thread fils après attente de %d

ms.\n",attente);ExitThread(12345678); //valeur arbitraire

}

Page 22: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 22

Insertion d’un fichier existant

Page 23: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 23

Chemin d’accès au fichier

Page 24: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 24

Après insertion du code

Page 25: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 25

Génération de THREAD1.exe

Build THREAD1.exe

Page 26: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 26

Exécution de THREAD1

• Vérifier la connexion et télécharger l’image– Target→Configure Remote Connexion…– Target→Download/Initialize

• Choisir et exécuter THREAD1– Target→Run Program

Dans la boîte choisir Run Program choisir THREAD1.exe ou renseigner la zone Execution command line

– Cliquer le bouton Run

Page 27: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 27

Résultat de l’exécution

Page 28: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 28

Application THREAD2

• Accès aux identificateurs de threads et aux handles par GetCurrentThreadId et GetCurrentThread

– ThreadId du thread courant– ThreadId du père– ThreadId du fils

• SuspendThread• ResumeThread

Page 29: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 29

Application THREAD2 : Main

• Récupération du ThreadId• Création d’un pseudo-handle personnel• Création du thread fils• Impression des valeurs• Réveil du thread fils après attente• Lectures des codes de retour du fils• Fermeture du handle fils• Retour au système

Page 30: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 30

THREAD2 main (1)

// THREAD2.cpp //Defines the entry point for the appli.#include "stdafx.h" //obligatoire avec l'option de compil. /Yu#define ATTENTE 1000 //durée de l'attente

void WINAPI A_MAIN (LPDWORD pAdresse_argument);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

Page 31: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 31

THREAD2 main (2)

{

HANDLE hFils;

HANDLE hPere;

DWORD threadId_pere=0;

DWORD threadId_fils=0;

LPDWORD lpThreadFilsId=&threadId_fils;

DWORD code_mis_par_le_fils;

Page 32: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 32

THREAD2 main (3)

printf("WinMain: début du thread primaire de THREAD2\n");

hFils=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)A_MAIN,NULL,0,lpThreadFilsId);

hPere=GetCurrentThread();threadId_pere=GetCurrentThreadId();printf("WinMain: handle_pere= %d handle_fils=

%d\n",hPere,hFils);printf("WinMain: threadId_pere= %d threadId_fils= %d\

n",threadId_pere,threadId_fils);Sleep(ATTENTE);ResumeThread(hFils);

Page 33: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 33

THREAD2 main (4)

GetExitCodeThread(hFils,&code_mis_par_le_fils);printf("WinMain: code de retour du thread fils : %d\

n",code_mis_par_le_fils);Sleep(ATTENTE);GetExitCodeThread(hFils,&code_mis_par_le_fils);printf("WinMain: code de retour du thread fils : %d\

n",code_mis_par_le_fils);CloseHandle(hFils);printf("WinMain: fin du thread primaire (main de

THREAD2)\n");getchar(); //attente d'un caractère pour…return (0);}

Page 34: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 34

THREAD2 fonction

#include "stdafx.h" //indispensable avec l'option /Yu…void WINAPI A_MAIN(LPDWORD pAdresse_argument){

DWORD threadId=0;HANDLE hLocal;hLocal=GetCurrentThread(); //crée un pseudo-handlethreadId=GetCurrentThreadId();printf("A_Main: threadId= %d hLocal= %d\n",threadId,hLocal);SuspendThread(hLocal);ExitThread(87654321);

}

Page 35: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 35

Mettre THREAD2 dans le noyau

Page 36: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 36

MAKE IMAGE

Page 37: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 37

Démarrer->Exécuter

Page 38: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 38

Parcourir

Page 39: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 39

Sélectionner THREAD2

Page 40: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 40

OK

Page 41: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 41

Résultat de l’exécution

Page 42: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 42

Application THREAD3

• Dans une nouvelle application, THREAD3, nous allons remplacer dans TRHEAD2 le paramètre ATTENTE par une valeur lue sur la ligne de commande.

• Suppression du #define ATTENTE• Remplacement des deux occurrences de ATTENTE par

l’appel à la fonction _wtoi() qui convertit la chaîne UNICODE donnée sur la ligne d’attente en un entier

• Nous supposerons que le paramètre fourni sur la ligne de commande est saisi correctement, car le but est de montrer l’accès à la ligne de commande et non de tester les chaînes proposées, soit par exemple 1000 ou 12345

• On peut imprimer la valeur lue par un printf

Page 43: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 43

THREAD3 main (1)

• Supprimer– #define ATTENTE 1000

• Remplacer les deux occurrences de– Sleep(ATTENTE); par– Sleep(_wtoi(lpCmdLine);

• THREAD3fonc identique à THRED2fonc• Générer la nouvelle image puis exécuter en

renseignant la boîte d’exécution avec le nom du programme suivi de 12345

Page 44: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 44

Résultat de l’exécution

Page 45: Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.

jc/md/lp-01/06 Threads 45

Conclusion

• Nous appris à créer des threads et à organiser les communications élémentaires entre un thread père et un thread fils