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 :

TThread et multiprocesseur


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 53
    Par défaut TThread et multiprocesseur
    Salut à tous,

    A chaque jour son petit sujet...

    Je travail sur la création de thread afin de faire du "parallèle". Voici le petit thread de chronométrage que j'ai "créé" :

    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
    #ifndef chronometreH
    #define chronometreH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    //---------------------------------------------------------------------------
    class ThChrono : public TThread
    {
    private:
    protected:
            void __fastcall Execute();
            void __fastcall AffMessage();
     
    public:
            __fastcall ThChrono(bool CreateSuspended);
     
            LARGE_INTEGER  start;      //!< The start time of the chronometer
            LARGE_INTEGER  tic;
            LARGE_INTEGER  FQPF;
     
            bool           HRPCAvail;  //!< Is there an available HRPC
     
            AnsiString millit;
            double result;
    };
    //---------------------------------------------------------------------------
    #endif
    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
    53
    54
    55
    56
    57
    #include <vcl.h>
    #pragma hdrstop
     
    #include "chronometre.h"
    #include "page_essai.h"
    #pragma package(smart_init)
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
     
    __fastcall ThChrono::ThChrono(bool CreateSuspended)
            : TThread(CreateSuspended)
    {
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    void __fastcall ThChrono::Execute()
    {
     
            HRPCAvail=QueryPerformanceCounter(&start); //memo du temps de start
            if (!HRPCAvail)   //si le compteur n'était pas disponible
            {
              start.LowPart = ::GetTickCount();   //basse resolution
              start.HighPart = 0;
            }
     
            while (!Terminated)
            {
               if (HRPCAvail) //si le compteur haute resolution était dispo
               {
                 QueryPerformanceCounter(&tic); //recup du temps
     
                 QueryPerformanceFrequency(&FQPF); //recup de la frequence
     
                 //resultat en msec
                 result=static_cast<double>(tic.QuadPart - start.QuadPart) * 1000
                  /static_cast<double>(FQPF.QuadPart);
               }
               else //si le compteur n'était pas disponible
               {
                 tic.LowPart = ::GetTickCount();
                 tic.HighPart = 0;
     
                 result = 0;
                 //resultat
                 result=tic.LowPart - start.LowPart;
     
               }
               millit = AnsiString(result);
               Synchronize(AffMessage);
            }
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    void __fastcall ThChrono::AffMessage()
    {
           ecran_essai->Label1->Caption = millit;
    }
    Je met créé entre guillemet car j'ai énormément pompé sur le code trouvé dans ce poste

    Ma question est de savoir s'il existe un moyen de s'assurer ou de forcer l'utilisation des différents cœurs du PC? Un coeur pour le process principal et un autre pour les threads.

    Même si mon process n'est composé que de tâches durant plusieurs centième de seconde, que ce chrono est "riche" pour mon utilisation, je préfère assuré le process.

  2. #2
    Membre très actif Avatar de nirgal76
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2007
    Messages
    923
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 923
    Par défaut
    Tu as la fonction SetThreadAffinityMask qui permet de définir les coeurs que pourras utiliser ton thread

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    DWORD_PTR WINAPI SetThreadAffinityMask(
    __in HANDLE hThread,
    __in DWORD_PTR dwThreadAffinityMask
    );

    hThread : premier paramètre, l'ID de ton thread
    dwThreadAffinityMask : le masque d'utilisation des cores. 1 bit par coeur. bit de poids faible pour le core n°1.
    exemple :
    pour n'utiliser que le core n°1, tu mets 0x1
    pour n'utiliser que le core n°2, tu mets 0x2
    pour n'utiliser que les core n°1 et 2, tu mets 0x3
    pour n'utiliser que le core n°3, tu mets 0x4
    pour n'utiliser que les core n°1 et 3, tu mets 0x5
    pour n'utiliser que les core n°2 et 3, tu mets 0x6
    pour n'utiliser que les core n°1, 2 et 3, tu mets 0x7
    ...
    Attention, tu dois donner un pointer sur un dword contenant le masque, pas le dword lui même

    DWORD mask=0x3;
    SetThreadAffinityMask(threadID, &mask);

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 53
    Par défaut
    Super merci Nirgal76. Ça parait assez simple à utiliser.

    Petites précisions :

    Ta fonction s'utilise dans la definition du thread ou dans le code qui lance le thread ?

    sur le ThreadID. Si je lance mon thread comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void __fastcall Tecran_essai::startClick(TObject *Sender)
    {
     
            chrono = new ThChrono(false);
     
    }
    Quel est le threadID (handle) ?

    //+++++++++++++++++++++++++++++++++++++++

    Pour la suite c'est plus un problème d'utilisation du thread que je rencontre. Mon premier code fonctionne mais j'aimerai que le label récupérant le temps chrono ne soit pas écrit en dur dans le thread. J'aimerai donc pouvoir spécifié à la création du thread où il doit écrite la donnée lors de la synchronisation. Voici donc le code que j'ai fait :

    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
    #ifndef chronometreH
    #define chronometreH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    //---------------------------------------------------------------------------
    class ThChrono : public TThread
    {
    private:
    protected:
            void __fastcall Execute();
            void __fastcall AffMessage();
     
    public:
            __fastcall ThChrono(bool CreateSuspended,AnsiString *data);
            AnsiString *Thdata;
     
            LARGE_INTEGER  start;      //!< The start time of the chronometer
            LARGE_INTEGER  tic;
            LARGE_INTEGER  FQPF;
     
            bool           HRPCAvail;  //!< Is there an available HRPC
     
            AnsiString millit;
            double result;
    };
    //---------------------------------------------------------------------------
    #endif
    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
    __fastcall ThChrono::ThChrono(bool CreateSuspended,AnsiString *data)
            : TThread(CreateSuspended)
    {
            Thdata = data;
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    void __fastcall ThChrono::Execute()
    {
     
            HRPCAvail=QueryPerformanceCounter(&start); //memo du temps de start
            if (!HRPCAvail)   //si le compteur n'était pas disponible
            {
              start.LowPart = ::GetTickCount();   //basse resolution
              start.HighPart = 0;
            }
     
            while (!Terminated)
            {
               if (HRPCAvail) //si le compteur haute resolution était dispo
               {
                 QueryPerformanceCounter(&tic); //recup du temps
     
                 QueryPerformanceFrequency(&FQPF); //recup de la frequence
     
                 //resultat en msec
                 result=static_cast<double>(tic.QuadPart - start.QuadPart) * 1000
                  /static_cast<double>(FQPF.QuadPart);
               }
               else //si le compteur n'était pas disponible
               {
                 tic.LowPart = ::GetTickCount();
                 tic.HighPart = 0;
     
                 result = 0;
                 //resultat
                 result=tic.LowPart - start.LowPart;
     
               }
               millit = AnsiString(result);
               Synchronize(AffMessage);
            }
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    void __fastcall ThChrono::AffMessage()
    {
           *Thdata = millit;
    }
    Avec l'appel du thread :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void __fastcall Tecran_essai::startClick(TObject *Sender)
    {
            chrono = new ThChrono(false,&(Label1->Caption));
    }
    Ça compile bien mais j'ai un bel access violation à l'exécution et c'est visiblement lors de l'exécution de la fonction du thread AffMessage().
    Une idée sur le pourquoi du comment?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 53
    Par défaut
    Un petit up car j'ai toujours mon problème.

  5. #5
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 41
    Par défaut
    Bonjour, tu passe quoi en paramètre à ton Thread ?

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    C'est surprenant que cela compile !
    tu ne peux pas passer une propriété (Caption) en paramètre var (* ou &), cela contournerait les accesseurs défini par __property !
    En Delphi, ça ne compilerait pas du tout ! le C++ se laisse berner !

    le plus propre serait de définir un Evènement dans lequel tu fournis le nouveau libellé, lancer par Synchronize évidemment !

    Quel est le threadID (handle) ?
    tu as une propriété Handle et ThreadID sur l'objet TThread, c'est cela que tu parles ?
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. TThread : EAccesViolation + EOSError
    Par Rodrigue dans le forum C++Builder
    Réponses: 12
    Dernier message: 09/01/2004, 15h19
  2. TThread et execl
    Par sebpatu dans le forum C++Builder
    Réponses: 2
    Dernier message: 17/11/2003, 00h02
  3. TThread et waitfor - descripteur non valide
    Par code34 dans le forum Langage
    Réponses: 2
    Dernier message: 27/10/2003, 23h44
  4. TThread: probleme de recuperation du Handle
    Par code34 dans le forum Langage
    Réponses: 8
    Dernier message: 07/09/2003, 03h04
  5. [TTHREAD] ne termine pas sont exécution
    Par Bbenj dans le forum Langage
    Réponses: 4
    Dernier message: 02/08/2002, 16h42

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