Bonjour,
Suite à ce sujet, je me suis penché sur les threads. Comme j'ai de nombreuses questions à propos de l'objet TThread de C++ Builder 6, je me permets de créer un sujet à part afin de poser mes diverses questions. J'ai cherché dans la FAQ, j'ai lu le tutoriel sur les threads et l'aide de C++ Builder mais je n'ai pas trouvé de réponses...
Au final, je souhaiterais réaliser un objet contenant un TTimer et un TThread, qui exécuterait une fonction à une heure donnée. J'ai commencé le développement de l'objet, le TTimer fonctionne, et à une heure donnée, il est prêt à exécuter ce que je souhaite.
Voici mes questions :
- peut-on choisir le moment de l'exécution d'un thread ? la méthode Execute doit être private donc on ne peut pas le lancer quand on le souhaite... J'ai remarqué que lors de la création d'une instance de TThread avec new, celui-ci était lancé à la FIN de la fonction ayant créé cette instance (voir le code exemple + bas). On peut le créer en le mettant par défaut en mode "suspendu", et faire un "resume" dès qu'on souhaite le lancer, mais dans ce cas... on ne peut le lancer qu'une fois !
- où mettre les appels au destructeur du thread "delete MonThread1" ? On ne peut pas le mettre après le new, sinon le thread est détruit avant même d'avoir été lancé... Faut-il utiliser FreeOnTerminate ? Cela correspond-t'il à sa destruction comme un delete à la fin de son exécution ?
- pour l'objet que je veux créer, comme un thread semble nécessairement être démarré avec un new, peut être faut-il que j'envoie à mon objet l'adresse de la fonction à exécuter, et non l'adresse d'un thread en le laissant suspend() lors de l'initialisation de l'objet ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 class TimerPlanning : public TTimer { private: void __fastcall VerifierTimer(TObject *); public: TThread *Thread; unsigned short PlanningHeure; unsigned short PlanningMinute; __fastcall TimerPlanning(TComponent *AOwner, unsigned short planning_heure, unsigned short planning_minute, TThread *thread); };
J'ai également mis en place un programme pour tester les threads, et notamment le fait qu'il se lance A LA FIN de la fonction dans laquelle ils sont appelés :
Ici, si j'appuie sur Button1, mon 1er thread se lance bien. Par contre, quand j'appuie sur Button2, à cause du "Sleep(3000)", le 2ème thread ne se lance pas juste après le new, le 1er thread est bloqué pendant les 3000 ms, puis les 2 threads sont relancés. Qu'est-ce qui se passe ?? Je pensais que dès que l'on faisait un new thread, celui-ci était exécuté ! Il ne s'exécute alors qu'APRES la FIN de la fonction qui l'a lancée ? C'est bizarre, non ? J'ai essayé avec un Application->ProcessMessages(); juste après le new, ça ne change rien...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 //--------------------------------------------------------------------------- // 1er thread //--------------------------------------------------------------------------- __fastcall TMonThread1::TMonThread1(bool CreateSuspended) : TThread(CreateSuspended) { } void __fastcall TMonThread1::Execute() { for(int i=0;i<500;i++) { Form1->Label1->Caption = String(i); Sleep(10); Application->ProcessMessages(); } } //--------------------------------------------------------------------------- // 2ème thread //--------------------------------------------------------------------------- __fastcall TMonThread2::TMonThread2(bool CreateSuspended) : TThread(CreateSuspended) { } void __fastcall TMonThread2::Execute() { for(int i=0;i<500;i++) { Form1->Label2->Caption = String(i); Sleep(10); Application->ProcessMessages(); } } //--------------------------------------------------------------------------- // Bouton pour lancer le 1er thread //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { TMonThread1 *MonThread = new TMonThread1(false); } //--------------------------------------------------------------------------- // Bouton pour lancer le 2ème thread //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { TMonThread2 *MonThread = new TMonThread2(false); Sleep(3000); }
Je sais que le Sleep(3000) est un événement bloquant. Mais si je mets par exemple à la place Form1->Label2->Caption = "fini", "fini" apparaît juste avant le lancement du thread... puisque la fonction Button2Click est executée entièrement avec son lancement... bizarre, alors que dans le code l'affichage de "fini" est après le thread !
Auriez-vous des idées pour ces questions et problèmes ? Evidemment, si vous ne pouvez pas répondre à toutes mes questions, je souhaite bien quelques explications sur les points que vous connaissez...
Si je ne suis pas clair, merci de me le faire savoir, j'essaierai de corriger mon message rapidement, car c'est assez urgent...
En vous remerciant par avance.
Partager