IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Question sur les TThreads


Sujet :

C++Builder

  1. #1
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Octobre 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Octobre 2012
    Messages : 24
    Points : 20
    Points
    20
    Par défaut Question sur les TThreads
    Bonjour,

    C'est ma première journée sur le TThreads

    Je galère un peu, alors voici mes questions

    Je créé un thread de calcul "non suspendu" sur l'appui d'un bouton

    Dans le Execute()
    je "prépare" 3 autres threads suspendus eux par contre pour une série d'opérations sur des grands entiers (la multiplication récursive de Karatsuba)

    voici une portion de ce Execute()

    Code cpp : 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
     
    bool __fastcall TLLTestsThread::TestExponentMersenne(jpNexp exponent_p)
    {
    ...
    kthr[VPS] = new TKaratsubaThread(kthrs_digits[VPS], g1,		  	a, 	b, L"_VPS");
    kthr[VG]  = new TKaratsubaThread(kthrs_digits[VG],  g_sn_digits, 	c, 	d, L"_VG");
    kthr[VD]  = new TKaratsubaThread(kthrs_digits[VD],  g_sn_digits + g, 	e,    	f, L"_VD");
    ...
    for (it=1; it<(exponent_p-2); it++)
    {
     thr_square_karatsuba(g_sn2_digits, g_sn_digits, g_sn2_digits_nb, g_sn_digits_nb, kthr);
     
     jpn2_sub(g_sn2m2_digits, g_sn2_digits, g_2.digits, g_sn2m2_digits_nb, g_sn2_digits_nb, 1);
     
     jpn2_div_for_ll(g_sn_digits, g_sn_d2n_digits, g_sn_m2n_digits, g_sn2m2_digits, g_mersenne_digits, g_mersenne_digits_nb, exponent_p);
    }

    dans ma fonction thr_square_karatsuba()

    j'appelle mes 3 threads avec Start()

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	kthr[VG]->Start();
    	kthr[VG]->WaitFor();
     
    	kthr[VD]->Start();
    	kthr[VD]->WaitFor();
     
    	kthr[VPS]->Start();
    	kthr[VPS]->WaitFor()

    Le soucis c'est que lors de la 1er iteration (it=1), les threads sont bien lancés
    puisque qu'ils démarrent a partir d'un mode (Suspended=true, Finished=false)

    lors du deuxième tour de boucle (it=2)
    les 3 threads sont apparemment dans un mode (Suspended=false, Finished=true)
    qui ne permet pas les 3 nouveaux appels de Start(), le 1er plante !

    et cela me produit une exception EThread

    Nom : Presse-papier02.jpg
Affichages : 172
Taille : 40,7 Ko

    Pourquoi ?
    les threads ne sont pas suspendus !?

    Merci pour votre aide

    PS:
    - je précise que j'ai géré les Terminated, même si je ne le mentionne pas
    - l'ordre
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread1->Start(),Thread1-> WaitFor(), Thread2->Start(),Thread2-> WaitFor(), Thread3->Start(),Thread3-> WaitFor()
    a été mis en place pour un débogage plus aisé, ensuite je ferais tout mes Start() à la suite puis tout mes WaitFor()

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    573
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 573
    Points : 713
    Points
    713
    Par défaut
    Salut , je me trompe peut etre mais si tu mettais tes new threads dans la boucle et envoyer un delete sur leur fin , çà ne fonctionnerait pas ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Octobre 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Octobre 2012
    Messages : 24
    Points : 20
    Points
    20
    Par défaut
    Salut,

    Oui, ça marche, j'ai essayé

    mais l'enchainement des new/delete dans la boucle ralenti fortement le traitement.

    Je me suis aperçu qu'une fois que la procédure Execute() avant fini son traitement, il était impossible de la relancer, j'ai vu l'information sur un site anglophone.

    La solution que j'ai imaginé et qui semble être efficace c'est de boucler dans les 3 threads Karatsuba

    Code cpp : 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
     
    void __fastcall TKaratsubaThread::Execute()
    {
    	//NameThreadForDebugging(System::String(L"KaratsubaThr")+thr_prefixe);
     
    	while (!Terminated)
    	{
    		KWaitForStart[quel_karatsuba]->WaitFor(60000);
    		KWaitForStart[quel_karatsuba]->ResetEvent();
     
    		if (Terminated)
    			break;
     
    		if (v1_digits_nb < K_MUL_LIMIT)
    		{
    			jpn2_mul_school(vr, v1, v1, vr_digits_nb, v1_digits_nb, v1_digits_nb);
    		}
    		else
    		{
    		jpNdigitsnb p = v1_digits_nb, p2 = p>>1, p3 = p-p2;
    		jpNdigit 	*vs, *vg, *vd, *vps, *vmtmp, *vm, *fin;
     
    			vs = vr + vr_digits_nb;
     
    			vg = jpn2_add(vs, v1, v1+p2, p3+1, p2, p3);						// vS = a + b
     
    			vd = jpn2_square_karatsuba(vg, v1, p2+p2, p2);					// vG = aa
     
    			vps = jpn2_square_karatsuba(vd, v1+p2, p3+p3, p3);					// vD = bb
     
    			vmtmp = jpn2_square_karatsuba(vps, vs, p3+1+p3+1, p3+1); 			// vM = (a + b)(c + d)
     
    			vm = jpn2_sub(vmtmp, vps, vg, p3+1+p3+1, p3+1+p3+1, p2+p2);			// vM = (a + b)(c + d) - ac
     
    			fin = jpn2_sub(vm, vmtmp, vd, p3+1+p3+1, p3+1+p3+1, p3+p3);			// vM = (a + b)(c + d) - ac - bd
     
    			jpn2_karatsuba_recompose(vr, vg, vm, vd, vr_digits_nb, p2+p2, p3+1+p3+1, p3+p3, p2);
    		}
     
    		KResultProduced[quel_karatsuba]->SetEvent();
    	}
    }

    ensuite dans thr_square_karatsuba(), de débloquer ces threads avec un évènement TEvent,
    pour faire 1 et un seul tour de boucle pour chaque thread karatsuba

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    		// je débloque mes 3 threads pour un tour de boucle chacun
    		KWaitForStart[gauche]->SetEvent();
    		KWaitForStart[droite]->SetEvent();
    		KWaitForStart[produit_sommes]->SetEvent();
     
    		// j’attends les résultats
    		KResultProduced[gauche]->WaitFor(100000);
    		KResultProduced[gauche]->ResetEvent();
    		KResultProduced[droite]->WaitFor(100000);
    		KResultProduced[droite]->ResetEvent();
    		KResultProduced[produit_sommes]->WaitFor(100000);
    		KResultProduced[produit_sommes]->ResetEvent();

    par contre j'ai découvert ça hier soir,

    donc mon usage des TEvent n'est pas encore parfait

  4. #4
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut
    pour ma part j'aborderais le problème de manière différente
    tout en sachant que la méthode execute d'un TThread doit impérativement avoir une boucle sans fin du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while (!Terminated)
    	{
              ..............................
             }
    je lui incorporais la fonction WaitForSingleObject de l'api Win32 avec comme paramètre le Handle d'un TEvent que j'aurais transmis au constructeur du Thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while (!Terminated)
    	{
              WaitForSingleObject (EventHandle,INFINITE)
     
             }
    de cette manière tu peux initialiser des Threads dans ton programme principal et les débloquer par un SetEvent


    lors de la destruction de ton programme tu devras également faire de même en n'oubliant pas de précéder ton SetEvent par un Terminate de ton thread


    de cette manière tu peux de économiser passablement de ressources systèmes et d'éviter lors d'une erreur dans un des thread de bloquer l'application dans son entier

    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  5. #5
    Membre à l'essai
    Homme Profil pro
    Programmeur
    Inscrit en
    Octobre 2012
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Octobre 2012
    Messages : 24
    Points : 20
    Points
    20
    Par défaut
    Salut

    tu est plus rapide avec Win32 (que je connais peu)
    mais au final le KWaitForStart[quel_karatsuba]->WaitFor(60000) utilise WaitForSingleObject()

    tu gagne 3 adressage KWaitForStart[], event->WaitFor() et this->Handle ainsi qu'un appel WaitFor()

    il y a-t-il une différence sur un calcul d'un mois, je n'ai aucune idée de l'incidence

Discussions similaires

  1. Petite question sur les performances de Postgres ...
    Par cb44 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 13/01/2004, 13h49
  2. question sur les vertex buffer et index buffer
    Par airseb dans le forum DirectX
    Réponses: 9
    Dernier message: 25/08/2003, 02h38
  3. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  4. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo