Communication avec thread

Communication avec thread - C++ - Programmation

Marsh Posté le 27-04-2005 à 14:06:38    

Hello,
 
J'ai un petit problème de communication avec mon thread.
Voila le plan de mon programme :
 
Thread:
 
{
 while(thumb à créé)
 {
    varthumb=false  
           creation thumb
    varthumb=true
 }
 
}
 
 
 
 
Prog:
{
 appui sur un bouton
        {
             Atente(varthumb==true)
             action
        }
}
 
En faite je cherche comment dans mon prog lui dire d'attendre que la variable varthumb sois mise a true par le thread.
J'ai bien esayer avec un while (varthumb==true ); mais ca me bouffe le proc a 100% et dc ca fait ramer le thread pour rien.
Y'a t'il une solution a mon prob?

Reply

Marsh Posté le 27-04-2005 à 14:06:38   

Reply

Marsh Posté le 27-04-2005 à 14:28:36    

Voire les solutions de synchro. Ca dépend de ce que tu utilises, mais c'est toujours pareil : mutex, event, section critique, ...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 27-04-2005 à 17:37:48    

while (varthumb==true )
  Sleep(2);
 
/me ->[]

Reply

Marsh Posté le 27-04-2005 à 20:27:42    


La deuxieme solution ne marche pas puisque le Sleep() fait dormir le prog principal et le thread.
Par contre pour la premiere solution je ne connai pas du tout ce que sont les "solution de synchro". Si quelqu'un pouvai me montrer commment ca marche et/ou me donner des exemples.
 
MERCI !

Reply

Marsh Posté le 27-04-2005 à 20:32:30    

Tu développes avec quelle bibliothèque (pour les threads) ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 27-04-2005 à 21:02:53    

j'utilise l'API windows je fais ca pur crée mon thread :
 
thread=CreateThread(NULL,NULL,ThreadProc,NULL,NULL,&ThreadId);

Reply

Marsh Posté le 27-04-2005 à 21:14:42    

Ah bon ben alors:
http://msdn.microsoft.com/library/ [...] zation.asp
Tu peux utiliser un event:
http://msdn.microsoft.com/library/ [...] bjects.asp
Ton thread déclenche l'event via SetEvent, ton prog attend que l'event soit signalé via WaitForSingleObject.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 27-04-2005 à 22:40:43    

Ok,  
J'ai regarder puis j'ai essayer, mais ca marche toujours po :(.  
Je fais la chose suivante :
 
appel du thread :
 

Code :
  1. MonEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  2. thread=CreateThread(NULL,NULL,ThreadProc,NULL,NULL,&ThreadId);
  3. SetThreadPriority(thread,THREAD_PRIORITY_LOWEST);


 
 
dans mon thread :
 

Code :
  1. DWORD WINAPI ThreadProc(LPVOID lpParam)
  2. {
  3.   //boucle tant qu'il y a des thum a créer
  4.   for (int i=15; i<FormVisuImage->ListeFichiersVisuThread->Count; i++)
  5.   {
  6.     ResetEvent(MonEvent);
  7.    
  8.     les choses qu'il fait .... ecriture des thumb sur le disque dur...
  9.     SetEvent(MonEvent);
  10.    
  11.   }
  12.   return 0;
  13. }


 
 
Dans mon Prog princ :  

Code :
  1. void __fastcall TFormVisuImage::Button6Click(TObject *Sender)
  2. {
  3.    if (WaitForSingleObject(MonEvent, 5000)== WAIT_OBJECT_0)
  4.    {
  5.     SuspendThread(thread);
  6.     FormSelectQuantitee->ShowModal();
  7.    }
  8. }


 
Donc je veux qu'il affiche la fenetre que si il a se trouve a la fin d'une boucle du thread, car si il est en plein milieu ca me fait des erreur vu que je les utilise apres.
 
Le prob , c que avec ce code la , ca m'arete tout lorsque je clique sur le bouton, le thread ne continu plus.
merci de ton aide !


Message édité par squellettor le 27-04-2005 à 22:54:48
Reply

Marsh Posté le 28-04-2005 à 10:16:56    

Citation :

le thread ne continu plus


ben c'est normal

Code :
  1. SuspendThread(thread)


pourquoi t'as mis ça ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 28-04-2005 à 10:37:15    

Ben J'ai mis ca car je voudrai qu'il fasse une pause sur le thread A ce moment la.
Mais je me suis mal exprimer pardon, en faite le prob c qu'il m'affiche pas ma fenetre....

Reply

Marsh Posté le 28-04-2005 à 10:37:15   

Reply

Marsh Posté le 28-04-2005 à 10:45:01    

Le thread ne s'arete pas a cause  de ce que je lui ai mis, il rentre jamais dans :
if (WaitForSingleObject(MonEvent, 5000)== WAIT_OBJECT_0)  
 
J'ai esayer d'afficher un msg dedan et ca marche po.
 
Par contre j'ai aussi essayer demettre un sleep (1000) dans mon thread apres le SetEvent. Et si je clique surmon bouton alors que le thread est en train de faire ce sleep ca marche, mais sinon il attend et le thread ne continu pas a tourner a coté.
Je sais po trop si je me suis bien exprimer, di moi si t'arrive po a me comprendre :s

Reply

Marsh Posté le 28-04-2005 à 11:16:27    

Vire le ResetEvent de ton thread. Y'en a un qui signale, l'autre qui traite le signal. Là ton thread il signale et juste après il dit "ah non finalement je signale plus". Ca vient peut etre de là.
Elle est longue ton opération d'"ecriture des thumb sur le disque dur" ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 04-05-2005 à 11:43:44    

Slt, dsl pour la reponse tardive.
Ben si je vire le ResetEvent ca marche po, car l'event est toujour a "set" dc il mon WaitForSingleObjet est toujour ok apres la premiere boucle ce que je ne veut pas.
Par contre j'ai remarquer que le WaitForSingleObjet ne marche po car quand il attend, le thread ne continu plus a tourner a coté, dc il ne trouve jamais.
Y'a t il une solution?
 
Pour repondre  ta question, vi l'operation d'ecriture des thumb dure longtemp ca peut durer plusieurs minute suivant le nombre de fichiers a traiter, je peu donc pas bloquer l'appli aussi longtemp.
 
merci de ton aide

Reply

Marsh Posté le 04-05-2005 à 11:52:07    

Je voulais dire déplace le ResetEvent. Il doit être fait après le WaitForSingleObject.
Le Wait, il wait. Ton thread client attend. L'autre n'est pas impacté. Je pige pas ton "marche po".
Si ça dure des minutes, n'oublie pas d'adapter ton 5000 alors, car 5000 = 5 sec. Si tu es sûr de toi met INFINITE.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 04-05-2005 à 11:53:23    

Ah si, l'autre thread est bloqué dans ton code, à cause du SuspendThread. SuspendThread ne devrait servir qu'au débogage. Vire le.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 04-05-2005 à 12:32:59    

en fait on s'est mal compris je croi. je peu pas maettre le ResetEvent apres le  WaitForSingleObject c pas ce que je veux.
Moi je veu que mon prog princiapl tourne avec le thread en meme temp. Mais quand on veut appuyer sur un bouton on attend que le thread soi en fin de boucle. Donc dans mon thread il faudrai que je lui dise  
 
debut boucle
{
  t'a pas le droi d'apuuyer sur les boutons
  {
    ...creation desx thumb
  }
  t'a le doirt d'appuyer  
}
fin de boucle
 
dc il aurai le droit d'appuyer que quand le thread est en fin de boucle. il faut donc un SetEvent et un Reset event dans le thread non?


Message édité par squellettor le 04-05-2005 à 12:35:08
Reply

Marsh Posté le 04-05-2005 à 12:43:12    

Et pour le SuspendThread, je suis obligé de le mettre, car quand il appui sur un boutton, on doit metttre en pause le thread pour effectuer d'autre action. En fait mon thread consiste a créee des thumb a partir d'un media(clé usb ou autre) et j'ai des boutons qui permette de copier certaines images selectionner du media sur le disque , donc pour eviter les conflits et augmenter la rapidité du prog je stop le thread , je fai ma copie et apres je relance le thread.
 

Reply

Marsh Posté le 04-05-2005 à 13:47:10    

Sauf que ta boucle, à peu de choses près c'est comme si tu avais:

Code :
  1. debut boucle
  2. {
  3.   t'a le doirt d'appuyer 
  4.   t'a pas le droi d'apuuyer sur les boutons
  5.   {
  6.     ...creation desx thumb
  7.   }
  8. }
  9. fin de boucle


donc t'as jamais le droit d'appuyer (enfin, pas plus de quelques msec).
Je crois deviner ce que tu veux faire. Vire le SuspendThread, et utilise un autre event, qui sert à relancer la boucle.

Code :
  1. debut boucle
  2. {
  3.   ->t'a pas le droi d'apuuyer sur les boutons
  4.   {
  5.     ...creation desx thumb
  6.   }
  7.   event "j'ai fini l'opération" : t'a le doirt d'appuyer 
  8.   wait "nouvelle itération"
  9. }
  10. fin de boucle


ton client attend que la boucle soit finie, et relance le thread en déclenchant le 2° event "nouvelle itération" qui débloque le 2° thread. SuspendThread c'est pas bon car ça demande des privilèges spéciaux (débogage) que ton utilisateur peux ne pas avoir.
 
Une question quand même : comment tu procèdes pour l'écriture des thumb ? Pourquoi un thread ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 04-05-2005 à 14:02:48    

je vais essayer mais je voi pas exactement comment je vais faire encore.
Pour l'ecriture des thumb, je charge mon image dans un objet image de borland de taille defini a la taille des thumb que je veu, puis je fais un Image->Picture->SaveToFile( ).
Mon prog permet de visualiser les photo d'un media page par page puis de selectionner des photo a faire developper.Le thread me permet de créer en avance les image thumb qui sont plus petite pendant que l'utilisateur visualise la premiere page avec les photos. Je créer des image thumb car c plus petit a afffiché et donc plus rapide a charger, si je met les images grande c trop lent, vu que les resolution sont generalement elevée.
 
En attendant merci , et t'a pas une adresse msn ce serai plus simple pour communiquer?

Reply

Marsh Posté le 04-05-2005 à 15:22:28    

Non j'ai pas msn. De plus un forum c'est fait pour partager l'info.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 06-05-2005 à 16:45:47    

Slt, J'ai essayer de avec un autre event pour arreter le thread au lieu de faire le SuspendThread, mais le prob est avant en fait. Dans mon prog des que je fais un WaitForSingleObject(MonEventThread,5000), il attend bien le signal , mais le thread ne continu pas a tourner dc il envoi jamais le signal :s  
Je comprend pas pkoi le thread ne tourne pas, y'a t il une commande special?

Reply

Marsh Posté le 06-05-2005 à 21:32:15    

Quel thread ne tourne plus ? Comment sais-tu qu'il ne tourne pas ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 08-05-2005 à 11:26:33    

L'event créé est en mode "Automatic reset" (car le 2e paramètre est à FALSE).
Je pense que tu devrais le passer en "Manual reset".
 
Voici un bout de code :
 
Création des events

Code :
  1. evtThreadNoWorkInProgress = CreateEvent(NULL, TRUE, TRUE, NULL); // manual reset, state=signaling
  2. evtThreadCanContinue      = CreateEvent(NULL, TRUE, TRUE, NULL); // manual reset, state=signaling


 
Thread de calcul des vignettes

Code :
  1. void ThreadProc(void)
  2. {
  3.   for(i=0; i<nombre_de_vignettes; i++)
  4.   {
  5.     ResetEvent(evtThreadNoWorkInProgress);
  6.     CalculerVignette(i);
  7.     SetEvent(evtThreadNoWorkInProgress);
  8.     WaitForSingleObjet(evtThreadCanContinue, INFINITE);
  9.   }
  10. }


 
Fonction appelée sur clic d'un bouton

Code :
  1. void OnClicOnMyButton(void)
  2. {
  3.   ResetEvent(evtThreadCanContinue); // on interdit au thread de continuer
  4.   WaitForSingleEvent(evtThreadNoWorkInProgress, INFINITE); // attend la fin du calcul courant
  5.   FaireQuelqueChosePendantQueLeThreadNeBossePlus();
  6.   SetEvent(evtThreadCanContinue); // autorise le thread à poursuivre
  7. }


 
Pour info, c'est d'une manière générale une mauvaise idée de laisser un thread de travail décider des interactions avec une interface graphique. Il appartient au thread de l'interface graphique de piloter les threads de travail et de décider si c'est éventuellement le bon moment pour faire une opération, quitte à geler certains threads.
 
Dit différemment, ce n'est pas au thread de travail (calcul des vignettes) de savoir si c'est le bon moment pour cliquer sur un bouton. Il vaut mieux qu'il se laisser bloquer/débloquer sans savoir pourquoi.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed